diff --git a/contracts/deploy/fix1148.ts b/contracts/deploy/fix1148.ts new file mode 100644 index 000000000..de31fa993 --- /dev/null +++ b/contracts/deploy/fix1148.ts @@ -0,0 +1,63 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { DisputeKitClassic, KlerosCore, SortitionModule } from "../typechain-types"; +import assert from "node:assert"; + +enum HomeChains { + ARBITRUM_ONE = 42161, + ARBITRUM_GOERLI = 421613, + HARDHAT = 31337, +} + +const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { ethers, deployments, getNamedAccounts, getChainId } = hre; + const { deploy, execute } = deployments; + const { AddressZero } = ethers.constants; + + // fallback to hardhat node signers on local network + const deployer = (await getNamedAccounts()).deployer ?? (await ethers.getSigners())[0].address; + const chainId = Number(await getChainId()); + console.log("Deploying to %s with deployer %s", HomeChains[chainId], deployer); + + const klerosCore = (await ethers.getContract("KlerosCore")) as KlerosCore; + const oldDisputeKit = (await ethers.getContract("DisputeKitClassic")) as DisputeKitClassic; + + await deploy("DisputeKitClassic", { + from: deployer, + args: [deployer, AddressZero], + log: true, + }); + + const newDisputeKit = (await ethers.getContract("DisputeKitClassic")) as DisputeKitClassic; + + await execute("DisputeKitClassic", { from: deployer, log: true }, "changeCore", klerosCore.address); + await execute("KlerosCore", { from: deployer, log: true }, "addNewDisputeKit", newDisputeKit.address, 0); + + const oldDisputeKitId = 1; + const newDisputeKitId = 2; + + assert( + await klerosCore.disputeKitNodes(oldDisputeKitId).then((node) => node.disputeKit === oldDisputeKit.address), + `wrong dispute kit id ${oldDisputeKitId}` + ); + assert( + await klerosCore.disputeKitNodes(newDisputeKitId).then((node) => node.disputeKit === newDisputeKit.address), + `wrong dispute kit id ${newDisputeKitId}` + ); + + await execute("KlerosCore", { from: deployer, log: true }, "enableDisputeKits", 1, [newDisputeKitId], true); // enable the new dispute kit in court 1 + await execute("KlerosCore", { from: deployer, log: true }, "enableDisputeKits", 2, [newDisputeKitId], true); // enable the new dispute kit in court 2 + await execute("KlerosCore", { from: deployer, log: true }, "enableDisputeKits", 3, [newDisputeKitId], true); // enable the new dispute kit in court 3 + + // Cannot disable the old DK because of https://github.com/kleros/kleros-v2/blob/d9adb8f54e8164eb01880296b4dd62b74cad3a0e/contracts/src/arbitration/KlerosCore.sol#L452 + // Does not seem correct + // await execute("KlerosCore", { from: deployer, log: true }, "enableDisputeKits", 1, [oldDisputeKitId], false); // disable the old dispute kit +}; + +deployArbitration.tags = ["Fix1148"]; +deployArbitration.skip = async ({ getChainId }) => { + const chainId = Number(await getChainId()); + return !HomeChains[chainId]; +}; + +export default deployArbitration; diff --git a/contracts/deployments/arbitrumGoerli/DisputeKitClassic.json b/contracts/deployments/arbitrumGoerli/DisputeKitClassic.json index 8b18c164d..7a43ab339 100644 --- a/contracts/deployments/arbitrumGoerli/DisputeKitClassic.json +++ b/contracts/deployments/arbitrumGoerli/DisputeKitClassic.json @@ -1,5 +1,5 @@ { - "address": "0x9ddf4a70295faaA695b8CF4F22177FA1f3a1B500", + "address": "0x439f92b61783A752462527f9dA9C6c6180C9253a", "abi": [ { "inputs": [ @@ -849,19 +849,19 @@ "type": "function" } ], - "transactionHash": "0x23f7713d0181ab7050677a8e8455a54e92a11b2f4b4faaae73c04388d70f40c2", + "transactionHash": "0x3501cc42baec8ec56bfe8d72a33814bcabb3bb58ced22ba81a270682f7fe10af", "receipt": { "to": null, "from": "0xF50E77f2A2B6138D16c6c7511562E5C33c4B15A3", - "contractAddress": "0x9ddf4a70295faaA695b8CF4F22177FA1f3a1B500", + "contractAddress": "0x439f92b61783A752462527f9dA9C6c6180C9253a", "transactionIndex": 1, - "gasUsed": "9123526", + "gasUsed": "3059359", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x356b4d676c1808cb8d232f9195fdd794d1803cab4bf6967d6ad7951a5d1efa0f", - "transactionHash": "0x23f7713d0181ab7050677a8e8455a54e92a11b2f4b4faaae73c04388d70f40c2", + "blockHash": "0x4540ca5939a081fd402bdf8915eb42a22bf295e97883a7b2aecb0eebbadf8b35", + "transactionHash": "0x3501cc42baec8ec56bfe8d72a33814bcabb3bb58ced22ba81a270682f7fe10af", "logs": [], - "blockNumber": 33436570, - "cumulativeGasUsed": "9123526", + "blockNumber": 34139950, + "cumulativeGasUsed": "3059359", "status": 1, "byzantium": true }, @@ -869,11 +869,11 @@ "0xF50E77f2A2B6138D16c6c7511562E5C33c4B15A3", "0x0000000000000000000000000000000000000000" ], - "numDeployments": 4, - "solcInputHash": "5cbc9a57c66318424bb771eed7e7b88c", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"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\":true,\"internalType\":\"uint256\",\"name\":\"_externalDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_party\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"Evidence\",\"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\"}],\"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\"}],\"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\":\"_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\":[{\"internalType\":\"uint256\",\"name\":\"_externalDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"submitEvidence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":{\"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.\"}},\"Evidence(uint256,address,string)\":{\"details\":\"To be raised when evidence is submitted. Should point to the resource (evidences are not to be stored on chain due to gas considerations).\",\"params\":{\"_evidence\":\"IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'\",\"_externalDisputeID\":\"Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right external dispute ID.\",\"_party\":\"The address of the party submiting the evidence. Note that 0x0 refers to evidence not submitted by any party.\"}},\"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\":{\"details\":\"Constructor.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"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)\":{\"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.\"},\"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)\":{\"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.\"}},\"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.\"}},\"submitEvidence(uint256,string)\":{\"details\":\"Submits evidence for a dispute.\",\"params\":{\"_evidence\":\"IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'.\",\"_externalDisputeID\":\"Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right evidence group ID.\"}},\"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.\",\"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.\"}}},\"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\":{\"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 v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\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 amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` 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 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport \\\"./interfaces/IDisputeKit.sol\\\";\\nimport \\\"./interfaces/ISortitionModule.sol\\\";\\nimport \\\"../libraries/SafeERC20.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 IArbitratorV2 {\\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 => bool) supportedDisputeKits; // True if DK with this ID is supported by the court.\\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 }\\n\\n struct Juror {\\n uint96[] courtIDs; // The IDs of courts where the juror's stake path ends. A stake path is a path from the general court to a court the juror directly staked in using `_setStake`.\\n mapping(uint96 => uint256) stakedPnk; // The amount of PNKs the juror has staked in the court in the form `stakedPnk[courtID]`.\\n mapping(uint96 => uint256) lockedPnk; // The amount of PNKs the juror has locked in the court in the form `lockedPnk[courtID]`.\\n }\\n\\n struct DisputeKitNode {\\n uint256 parent; // Index of the parent dispute kit. If it's 0 then this DK is a root.\\n uint256[] children; // List of child dispute kits.\\n IDisputeKit disputeKit; // The dispute kit implementation.\\n uint256 depthLevel; // How far this DK is from the root. 0 for root DK.\\n bool disabled; // True if the dispute kit is disabled and can't be used. This parameter is added preemptively to avoid storage changes in the future.\\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 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 uint96 public constant FORKING_COURT = 0; // Index of the forking court.\\n uint96 public constant GENERAL_COURT = 1; // Index of the default (general) court.\\n uint256 public constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent.\\n uint256 public constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n uint256 public constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\n uint256 public constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 public constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n uint256 public constant SEARCH_ITERATIONS = 10; // Number of iterations to search for suitable parent court before jumping to the top court.\\n IERC20 public constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\n address public governor; // The governor of the contract.\\n IERC20 public pinakion; // The Pinakion token contract.\\n // TODO: interactions with jurorProsecutionModule.\\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 DisputeKitNode[] public disputeKitNodes; // The list of DisputeKitNode, indexed by DisputeKitID.\\n Dispute[] public disputes; // The disputes.\\n mapping(address => Juror) internal jurors; // The jurors.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event StakeSet(address indexed _address, uint256 _courtID, uint256 _amount);\\n event StakeDelayed(address indexed _address, uint256 _courtID, uint256 _amount, uint256 _penalty);\\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 uint256 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(\\n uint256 indexed _disputeKitID,\\n IDisputeKit indexed _disputeKitAddress,\\n uint256 indexed _parent\\n );\\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\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n /// @dev Constructor.\\n /// @param _governor The governor'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 constructor(\\n address _governor,\\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 ) {\\n governor = _governor;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a node has no parent.\\n disputeKitNodes.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKitNodes.push(\\n DisputeKitNode({\\n parent: NULL_DISPUTE_KIT,\\n children: new uint256[](0),\\n disputeKit: _disputeKit,\\n depthLevel: 0,\\n disabled: false\\n })\\n );\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit, NULL_DISPUTE_KIT);\\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 emit CourtCreated(\\n 1,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n new uint256[](0)\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\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 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 `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 /// @param _parent The ID of the parent dispute kit. It is left empty when root DK is created.\\n /// Note that the root DK must be supported by the general court.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress, uint256 _parent) external onlyByGovernor {\\n uint256 disputeKitID = disputeKitNodes.length;\\n if (_parent >= disputeKitID) revert InvalidDisputKitParent();\\n uint256 depthLevel;\\n if (_parent != NULL_DISPUTE_KIT) {\\n depthLevel = disputeKitNodes[_parent].depthLevel + 1;\\n // It should be always possible to reach the root from the leaf with the defined number of search iterations.\\n if (depthLevel >= SEARCH_ITERATIONS) revert DepthLevelMax();\\n }\\n disputeKitNodes.push(\\n DisputeKitNode({\\n parent: _parent,\\n children: new uint256[](0),\\n disputeKit: _disputeKitAddress,\\n depthLevel: depthLevel,\\n disabled: false\\n })\\n );\\n\\n disputeKitNodes[_parent].children.push(disputeKitID);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress, _parent);\\n if (_parent == NULL_DISPUTE_KIT) {\\n // A new dispute kit tree root should always be supported by the General court.\\n _enableDisputeKit(GENERAL_COURT, disputeKitID, true);\\n }\\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] >= disputeKitNodes.length) {\\n revert WrongDisputeKitIndex();\\n }\\n court.supportedDisputeKits[_supportedDisputeKits[i]] = true;\\n }\\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 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 if (_courtID != GENERAL_COURT && courts[courts[_courtID].parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < courts[_courtID].children.length; i++) {\\n if (courts[courts[_courtID].children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n courts[_courtID].minStake = _minStake;\\n courts[_courtID].hiddenVotes = _hiddenVotes;\\n courts[_courtID].alpha = _alpha;\\n courts[_courtID].feeForJuror = _feeForJuror;\\n courts[_courtID].jurorsForCourtJump = _jurorsForCourtJump;\\n courts[_courtID].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] >= disputeKitNodes.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n if (_courtID == GENERAL_COURT && disputeKitNodes[_disputeKitIDs[i]].parent == NULL_DISPUTE_KIT) {\\n revert CannotDisableRootDKInGeneral();\\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 CurrencyRate storage rate = currencyRates[_feeToken];\\n rate.rateInEth = _rateInEth;\\n rate.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 _stake The new stake.\\n function setStake(uint96 _courtID, uint256 _stake) external {\\n if (!_setStakeForAccount(msg.sender, _courtID, _stake, 0)) revert StakingFailed();\\n }\\n\\n function setStakeBySortitionModule(address _account, uint96 _courtID, uint256 _stake, uint256 _penalty) external {\\n if (msg.sender != address(sortitionModule)) revert WrongCaller();\\n _setStakeForAccount(_account, _courtID, _stake, _penalty);\\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 require(_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount), \\\"Transfer failed\\\");\\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 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 = disputeKitNodes[disputeKitID].disputeKit;\\n Court storage court = courts[dispute.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 !disputeKitNodes[round.disputeKitID].disputeKit.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 !disputeKitNodes[round.disputeKitID].disputeKit.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 = disputeKitNodes[round.disputeKitID].disputeKit;\\n\\n uint256 startIndex = round.drawnJurors.length;\\n uint256 endIndex = startIndex + _iterations <= round.nbVotes ? startIndex + _iterations : round.nbVotes;\\n\\n for (uint256 i = startIndex; i < endIndex; i++) {\\n address drawnAddress = disputeKit.draw(_disputeID);\\n if (drawnAddress != address(0)) {\\n jurors[drawnAddress].lockedPnk[dispute.courtID] += round.pnkAtStakePerJuror;\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n }\\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(disputeKitNodes[round.disputeKitID].disputeKit)) 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 for (uint256 i = 0; i < SEARCH_ITERATIONS; i++) {\\n if (courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n break;\\n } else if (disputeKitNodes[newDisputeKitID].parent != NULL_DISPUTE_KIT) {\\n newDisputeKitID = disputeKitNodes[newDisputeKitID].parent;\\n } else {\\n // DK's parent has 0 index, that means we reached the root DK (0 depth level).\\n // Jump to the next parent court if the current court doesn't support any DK from this tree.\\n // Note that we don't reset newDisputeKitID in this case as, a precaution.\\n newCourtID = courts[newCourtID].parent;\\n }\\n }\\n // We didn't find a court that is compatible with DK from this tree, so we jump directly to the top court.\\n // Note that this can only happen when disputeKitID is at its root, and each root DK is supported by the top court by default.\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n newCourtID = GENERAL_COURT;\\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 IDisputeKit disputeKit = disputeKitNodes[extraRound.disputeKitID].disputeKit;\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKit.createDispute(_disputeID, _numberOfChoices, _extraData, extraRound.nbVotes);\\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 /// @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 {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n Round storage round = dispute.rounds[_round];\\n IDisputeKit disputeKit = disputeKitNodes[round.disputeKitID].disputeKit;\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRoundCache = round.pnkPenalties; // For saving gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\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 pnkPenaltiesInRoundCache = _executePenalties(\\n ExecuteParams(_disputeID, _round, coherentCount, numberOfVotesInRound, pnkPenaltiesInRoundCache, i)\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams(_disputeID, _round, coherentCount, numberOfVotesInRound, pnkPenaltiesInRoundCache, i)\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRoundCache) {\\n round.pnkPenalties = pnkPenaltiesInRoundCache; // 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 = disputeKitNodes[round.disputeKitID].disputeKit;\\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 );\\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 jurors[account].lockedPnk[dispute.courtID] -= penalty;\\n\\n // Apply the penalty to the staked PNKs\\n if (jurors[account].stakedPnk[dispute.courtID] >= courts[dispute.courtID].minStake + penalty) {\\n // The juror still has enough staked PNKs after penalty for this court.\\n uint256 newStake = jurors[account].stakedPnk[dispute.courtID] - penalty;\\n _setStakeForAccount(account, dispute.courtID, newStake, penalty);\\n } else if (jurors[account].stakedPnk[dispute.courtID] != 0) {\\n // The juror does not have enough staked PNKs after penalty for this court, unstake them.\\n _setStakeForAccount(account, dispute.courtID, 0, penalty);\\n }\\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 = disputeKitNodes[round.disputeKitID].disputeKit;\\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 );\\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 jurors[account].lockedPnk[dispute.courtID] -= pnkLocked;\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (jurors[account].stakedPnk[dispute.courtID] == 0) {\\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 = disputeKitNodes[round.disputeKitID].disputeKit;\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(\\n uint256 _disputeID,\\n uint256 _round\\n )\\n external\\n view\\n returns (\\n uint256 disputeKitID,\\n uint256 pnkAtStakePerJuror,\\n uint256 totalFeesForJurors,\\n uint256 nbVotes,\\n uint256 repartitions,\\n uint256 pnkPenalties,\\n address[] memory drawnJurors,\\n uint256 sumFeeRewardPaid,\\n uint256 sumPnkRewardPaid,\\n IERC20 feeToken\\n )\\n {\\n Round storage round = disputes[_disputeID].rounds[_round];\\n return (\\n round.disputeKitID,\\n round.pnkAtStakePerJuror,\\n round.totalFeesForJurors,\\n round.nbVotes,\\n round.repartitions,\\n round.pnkPenalties,\\n round.drawnJurors,\\n round.sumFeeRewardPaid,\\n round.sumPnkRewardPaid,\\n round.feeToken\\n );\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 staked, uint256 locked, uint256 nbCourts) {\\n Juror storage juror = jurors[_juror];\\n staked = juror.stakedPnk[_courtID];\\n locked = juror.lockedPnk[_courtID];\\n nbCourts = juror.courtIDs.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 non-primitive properties of a specified dispute kit node.\\n /// @param _disputeKitID The ID of the dispute kit.\\n /// @return children Indexes of children of this DK.\\n function getDisputeKitChildren(uint256 _disputeKitID) external view returns (uint256[] memory) {\\n return disputeKitNodes[_disputeKitID].children;\\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 Court storage court = courts[_courtID];\\n timesPerPeriod = court.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 getDisputeKitNodesLength() external view returns (uint256) {\\n return disputeKitNodes.length;\\n }\\n\\n /// @dev Gets the dispute kit for a specific `_disputeKitID`.\\n /// @param _disputeKitID The ID of the dispute kit.\\n function getDisputeKit(uint256 _disputeKitID) external view returns (IDisputeKit) {\\n return disputeKitNodes[_disputeKitID].disputeKit;\\n }\\n\\n /// @dev Gets the court identifiers where a specific `_juror` has staked.\\n /// @param _juror The address of the juror.\\n function getJurorCourtIDs(address _juror) public view returns (uint96[] memory) {\\n return jurors[_juror].courtIDs;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n CurrencyRate storage rate = currencyRates[_toToken];\\n return (_amountInEth * 10 ** rate.rateDecimals) / rate.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.\\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 Sets the specified juror's stake in a court.\\n /// `O(n + p * log_k(j))` where\\n /// `n` is the number of courts the juror has staked in,\\n /// `p` is the depth of the court tree,\\n /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,\\n /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.\\n /// @param _account The address of the juror.\\n /// @param _courtID The ID of the court.\\n /// @param _stake The new stake.\\n /// @param _penalty Penalized amount won't be transferred back to juror when the stake is lowered.\\n /// @return succeeded True if the call succeeded, false otherwise.\\n function _setStakeForAccount(\\n address _account,\\n uint96 _courtID,\\n uint256 _stake,\\n uint256 _penalty\\n ) internal returns (bool succeeded) {\\n if (_courtID == FORKING_COURT || _courtID > courts.length) return false;\\n\\n Juror storage juror = jurors[_account];\\n uint256 currentStake = juror.stakedPnk[_courtID];\\n\\n if (_stake != 0) {\\n // Check against locked PNKs in case the min stake was lowered.\\n if (_stake < courts[_courtID].minStake || _stake < juror.lockedPnk[_courtID]) return false;\\n }\\n\\n ISortitionModule.preStakeHookResult result = sortitionModule.preStakeHook(_account, _courtID, _stake, _penalty);\\n if (result == ISortitionModule.preStakeHookResult.failed) {\\n return false;\\n } else if (result == ISortitionModule.preStakeHookResult.delayed) {\\n emit StakeDelayed(_account, _courtID, _stake, _penalty);\\n return true;\\n }\\n\\n uint256 transferredAmount;\\n if (_stake >= currentStake) {\\n transferredAmount = _stake - currentStake;\\n if (transferredAmount > 0) {\\n if (pinakion.safeTransferFrom(_account, address(this), transferredAmount)) {\\n if (currentStake == 0) {\\n juror.courtIDs.push(_courtID);\\n }\\n } else {\\n return false;\\n }\\n }\\n } else {\\n if (_stake == 0) {\\n // Keep locked PNKs in the contract and release them after dispute is executed.\\n transferredAmount = currentStake - juror.lockedPnk[_courtID] - _penalty;\\n if (transferredAmount > 0) {\\n if (pinakion.safeTransfer(_account, transferredAmount)) {\\n for (uint256 i = juror.courtIDs.length; i > 0; i--) {\\n if (juror.courtIDs[i - 1] == _courtID) {\\n juror.courtIDs[i - 1] = juror.courtIDs[juror.courtIDs.length - 1];\\n juror.courtIDs.pop();\\n break;\\n }\\n }\\n } else {\\n return false;\\n }\\n }\\n } else {\\n transferredAmount = currentStake - _stake - _penalty;\\n if (transferredAmount > 0) {\\n if (!pinakion.safeTransfer(_account, transferredAmount)) {\\n return false;\\n }\\n }\\n }\\n }\\n\\n // Update juror's records.\\n juror.stakedPnk[_courtID] = _stake;\\n\\n sortitionModule.setStake(_account, _courtID, _stake);\\n emit StakeSet(_account, _courtID, _stake);\\n return true;\\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 >= disputeKitNodes.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 UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error DepthLevelMax();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableRootDKInGeneral();\\n error ArraysLengthMismatch();\\n error StakingFailed();\\n error WrongCaller();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\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 DisputeKitOnly();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n}\\n\",\"keccak256\":\"0xbbe5c690d5e8c80fb1802d46a2495c6cf3737cf912a0999377c1191df4aaa4fe\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/BaseDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\n\\nimport \\\"../interfaces/IDisputeKit.sol\\\";\\nimport \\\"../KlerosCore.sol\\\";\\n\\n/// @title BaseDisputeKit\\n/// Provides common basic behaviours to the Dispute Kit implementations.\\nabstract contract BaseDisputeKit is IDisputeKit {\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n\\n // ************************************* //\\n // * Function 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 /// @dev Constructor.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n constructor(address _governor, KlerosCore _core) {\\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 Checks that the chosen address satisfies certain conditions for being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return Whether the address can be drawn or not.\\n function _postDrawCheck(uint256 _coreDisputeID, address _juror) internal virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xa33f365553132a9cc4f0b5fdfe9e5be2337d13dfca71a65835450de17496b93f\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\n\\nimport \\\"./BaseDisputeKit.sol\\\";\\nimport \\\"../interfaces/IEvidence.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 BaseDisputeKit, IEvidence {\\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 => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address => mapping(uint256 => 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 }\\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 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\\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 notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n /** @dev Constructor.\\n * @param _governor The governor's address.\\n * @param _core The KlerosCore arbitrator.\\n */\\n constructor(address _governor, KlerosCore _core) BaseDisputeKit(_governor, _core) {}\\n\\n // ************************ //\\n // * Governance * //\\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 /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID\\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 // TODO: Handle the situation when no one has staked yet.\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, round.votes.length);\\n\\n if (_postDrawCheck(_coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\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 == KlerosCore.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 == KlerosCore.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 ||\\n round.votes[_voteIDs[i]].commit == keccak256(abi.encodePacked(_choice, _justification, _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 /// @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\\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 /// @dev Submits evidence for a dispute.\\n /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right evidence group ID.\\n /// @param _evidence IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'.\\n function submitEvidence(uint256 _externalDisputeID, string calldata _evidence) external {\\n emit Evidence(_externalDisputeID, msg.sender, _evidence);\\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 == KlerosCore.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 ) 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 /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return Whether the address can be drawn or not.\\n function _postDrawCheck(uint256 _coreDisputeID, address _juror) internal view override returns (bool) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, uint256 lockedAmountPerJuror, , , , , , , , ) = core.getRoundInfo(\\n _coreDisputeID,\\n core.getNumberOfRounds(_coreDisputeID) - 1\\n );\\n (uint256 staked, uint256 locked, ) = core.getJurorBalance(_juror, courtID);\\n (, , uint256 minStake, , , , ) = core.courts(courtID);\\n return staked >= locked + lockedAmountPerJuror && staked >= minStake;\\n }\\n}\\n\",\"keccak256\":\"0x59f6b6b54d204ba3194257220f5e1361b9f515ed89c0fb865f04fcf14bf13742\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.18;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// 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 _arbitrableDisputeID The identifier of the dispute in the Arbitrable 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 _arbitrableDisputeID,\\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\":\"0x389326b1f749454ed179bdac2f9d6ce24a1ef944bbce976ca78b93f4e173354a\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.18;\\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\":\"0x453943ba5ccc94b9b9cdfd4afd3678682d62d8b90fe16b43e90215387d2f6a51\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\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 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 /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID) 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 /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\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\":\"0x322c20f62706a690bc03f188531b77fe8eac85a9474f17fe15c2db494904c932\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IEvidence.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.18;\\n\\n/// @title IEvidence\\ninterface IEvidence {\\n /// @dev To be raised when evidence is submitted. Should point to the resource (evidences are not to be stored on chain due to gas considerations).\\n /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right external dispute ID.\\n /// @param _party The address of the party submiting the evidence. Note that 0x0 refers to evidence not submitted by any party.\\n /// @param _evidence IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'\\n event Evidence(uint256 indexed _externalDisputeID, address indexed _party, string _evidence);\\n}\\n\",\"keccak256\":\"0x3350da62267a5dad4616dafd9916fe3bfa4cdabfce124709ac3b7d087361e8c4\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\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 enum preStakeHookResult {\\n ok,\\n delayed,\\n failed\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(address _account, uint96 _courtID, uint256 _value) external;\\n\\n function setJurorInactive(address _account) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _voteID) external view returns (address);\\n\\n function preStakeHook(\\n address _account,\\n uint96 _courtID,\\n uint256 _stake,\\n uint256 _penalty\\n ) external returns (preStakeHookResult);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x28911aa78669746f40c4c3bce723db21600a49a74142c0fe378680b1b356d633\",\"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.18;\\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\":\"0x37a19df56a98cd466fb6e70b8c56e13bfc439221bfabd8c5108d36d0e3ffc0e5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162003ada38038062003ada83398101604081905262000034916200007f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055620000be565b6001600160a01b03811681146200007c57600080fd5b50565b600080604083850312156200009357600080fd5b8251620000a08162000066565b6020840151909250620000b38162000066565b809150509250929050565b613a0c80620000ce6000396000f3fe60806040526004361061016c5760003560e01c8063751accd0116100cc578063b6ede5401161007a578063b6ede540146104ac578063ba66fde7146104cc578063be467604146104ec578063da3beb8c14610502578063e349ad30146103d4578063e4c0aaf414610522578063f2f4eb261461054257600080fd5b8063751accd0146103b4578063796490f9146103d45780637c04034e146103ea5780638e4264601461040a578063a6a7f0eb1461042a578063a7cc08fe1461044a578063b34bfaa81461049657600080fd5b80634b2f0ea0116101295780634b2f0ea0146102965780634fe264fb146102ab578063564a565d146102cb5780635c92e2f6146102fa57806365540b961461031a57806369f3f041146103475780636d4cd8ea1461039457600080fd5b80630baa64d1146101715780630c340a24146101a65780631200aabc146101de5780631c3db16d14610219578063362c3479146102565780633b30414714610276575b600080fd5b34801561017d57600080fd5b5061019161018c366004612d5c565b610562565b60405190151581526020015b60405180910390f35b3480156101b257600080fd5b506000546101c6906001600160a01b031681565b6040516001600160a01b03909116815260200161019d565b3480156101ea57600080fd5b5061020b6101f9366004612d5c565b60036020526000908152604090205481565b60405190815260200161019d565b34801561022557600080fd5b50610239610234366004612d5c565b6105d9565b60408051938452911515602084015215159082015260600161019d565b34801561026257600080fd5b5061020b610271366004612d8d565b610747565b34801561028257600080fd5b506101c6610291366004612d5c565b610b1d565b6102a96102a4366004612dca565b610e29565b005b3480156102b757600080fd5b5061020b6102c6366004612dec565b611690565b3480156102d757600080fd5b506102eb6102e6366004612d5c565b6117d3565b60405161019d93929190612e68565b34801561030657600080fd5b506102a9610315366004612edd565b611899565b34801561032657600080fd5b5061033a610335366004612d5c565b611ba6565b60405161019d9190612f2f565b34801561035357600080fd5b50610367610362366004612dec565b611c6a565b604080519687529415156020870152938501929092526060840152608083015260a082015260c00161019d565b3480156103a057600080fd5b506101916103af366004612d5c565b611d22565b3480156103c057600080fd5b506102a96103cf366004613010565b611d99565b3480156103e057600080fd5b5061020b61271081565b3480156103f657600080fd5b506102a961040536600461307c565b611e6b565b34801561041657600080fd5b506102a9610425366004613114565b612547565b34801561043657600080fd5b506102a9610445366004613172565b612593565b34801561045657600080fd5b5061046a610465366004612dec565b6125dc565b604080516001600160a01b0390951685526020850193909352918301521515606082015260800161019d565b3480156104a257600080fd5b5061020b614e2081565b3480156104b857600080fd5b506102a96104c73660046131bd565b6126a2565b3480156104d857600080fd5b506101916104e7366004612dec565b612877565b3480156104f857600080fd5b5061020b61138881565b34801561050e57600080fd5b5061020b61051d366004612dca565b612912565b34801561052e57600080fd5b506102a961053d366004613114565b612a65565b34801561054e57600080fd5b506001546101c6906001600160a01b031681565b60008181526003602052604081205460028054839290811061058657610586613217565b600091825260208220600590910201805490925082906105a890600190613243565b815481106105b8576105b8613217565b60009182526020909120600c90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061060557610605613217565b6000918252602082206005909102018054909250829061062790600190613243565b8154811061063757610637613217565b60009182526020909120600c90910201600381015460ff169450905083610662578060010154610665565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156106b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d89190613282565b50909350600492506106e8915050565b8160048111156106fa576106fa6132e9565b0361073d57600061070a88611ba6565b9050805160010361073b578060008151811061072857610728613217565b6020026020010151965060009550600194505b505b5050509193909250565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190613282565b509350505050806108115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b60008681526003602052604081205460028054909190811061083557610835613217565b6000918252602080832088845260036005909302019182019052604082205481549193508391811061086957610869613217565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600c9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa1580156108c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e891906132ff565b5050600087815260078401602052604090205490915060ff16610932576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610a77565b8086036109a75760008681526006830160205260409020546109555760006109a0565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610996919061333b565b6109a09190613352565b9450610a77565b600081815260078301602052604090205460ff16610a775781600601600083600a016001815481106109db576109db613217565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610a1157610a11613217565b9060005260206000200154815260200190815260200160002054610a359190613374565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610a6a919061333b565b610a749190613352565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610b11576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b6001546000906001600160a01b03163314610b4a5760405162461bcd60e51b815260040161080890613387565b600082815260036020526040902054600280548492908110610b6e57610b6e613217565b600091825260209091206002600590920201015460ff1615610ba25760405162461bcd60e51b8152600401610808906133cb565b600083815260036020526040812054600280549091908110610bc657610bc6613217565b60009182526020822060059091020180549092508290610be890600190613243565b81548110610bf857610bf8613217565b90600052602060002090600c020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c819190613402565b60015460405163564a565d60e01b8152600481018990529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf49190613282565b50508554604051632638506b60e11b81526001600160601b03851660048201819052602482018d90526044820192909252939450926001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190613402565b9650610d8c8888612ab1565b15610e1957604080516080810182526001600160a01b03898116825260006020808401828152948401828152606085018381528a5460018082018d558c8652939094209551600490940290950180546001600160a01b0319169390941692909217835593519382019390935591516002830155516003909101805460ff1916911515919091179055610e1e565b600096505b505050505050919050565b600082815260036020526040902054600280548492908110610e4d57610e4d613217565b600091825260209091206002600590920201015460ff1615610e815760405162461bcd60e51b8152600401610808906133cb565b600083815260036020526040812054600280549091908110610ea557610ea5613217565b906000526020600020906005020190508060010154831115610f095760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610808565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7a919061341f565b91509150814210158015610f8d57508042105b610fd25760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610808565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611013573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103791906132ff565b5050905086810361104c5761271091506110cd565b61271061138861105c8686613243565b611066919061333b565b6110709190613352565b61107a8542613243565b106110c75760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610808565b614e2091505b845460009086906110e090600190613243565b815481106110f0576110f0613217565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600c949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111739190613443565b61117d9190613243565b60008a815260078401602052604090205490915060ff16156111e15760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610808565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561122b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124f9190613443565b90506000612710611260878461333b565b61126a9190613352565b6112749083613374565b60008c8152600686016020526040812054919250908211156113255760008c815260068601602052604090205434906112ad9084613243565b116112d25760008c81526006860160205260409020546112cd9083613243565b6112d4565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161131c929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611351908490613374565b909155505060008c815260068601602052604081208054839290611376908490613374565b909155505060008c815260068601602052604090205482116114485760008c8152600686016020526040812054600987018054919290916113b8908490613374565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611653578285600901546114659190613243565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa1580156114b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d7919061345c565b156114f05760028a01805460ff191660011790556115d3565b895460038b016000611503876001613374565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600c02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161157e91815260200190565b602060405180830381865afa15801561159b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bf9190613443565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b8152600401611620939291906134b1565b6000604051808303818588803b15801561163957600080fd5b505af115801561164d573d6000803e3d6000fd5b50505050505b8034111561168157336108fc6116698334613243565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b6000838152600360205260408120546002805483929081106116b4576116b4613217565b600091825260208083208784526003600590930201918201905260408220548154919350839181106116e8576116e8613217565b90600052602060002090600c0201600001848154811061170a5761170a613217565b600091825260208220600154604051631c3db16d60e01b815260048082018c905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178c91906132ff565b506003850154919350915060ff1680156117b0575081836002015414806117b05750805b156117c3576127109450505050506117cc565b60009450505050505b9392505050565b600281815481106117e357600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff909116929161181690613477565b80601f016020809104026020016040519081016040528092919081815260200182805461184290613477565b801561188f5780601f106118645761010080835404028352916020019161188f565b820191906000526020600020905b81548152906001019060200180831161187257829003601f168201915b5050505050905083565b6000848152600360205260409020546002805486929081106118bd576118bd613217565b600091825260209091206002600590920201015460ff16156118f15760405162461bcd60e51b8152600401610808906133cb565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa15801561193b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195f9190613282565b509093506001925061196f915050565b816004811115611981576119816132e9565b146119de5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610808565b82611a1b5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610808565b600086815260036020526040812054600280549091908110611a3f57611a3f613217565b60009182526020822060059091020180549092508290611a6190600190613243565b81548110611a7157611a71613217565b90600052602060002090600c0201905060005b86811015611b3f573382898984818110611aa057611aa0613217565b9050602002013581548110611ab757611ab7613217565b60009182526020909120600490910201546001600160a01b031614611aee5760405162461bcd60e51b81526004016108089061354b565b8582898984818110611b0257611b02613217565b9050602002013581548110611b1957611b19613217565b600091825260209091206001600490920201015580611b3781613582565b915050611a84565b5086869050816005016000828254611b579190613374565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611b94908b908b908b906135cd565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611bcc57611bcc613217565b60009182526020822060059091020180549092508290611bee90600190613243565b81548110611bfe57611bfe613217565b90600052602060002090600c0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c5c57602002820191906000526020600020905b815481526020019060010190808311611c48575b505050505092505050919050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611c9b57611c9b613217565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611ccf57611ccf613217565b600091825260208083206001600c909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611d4657611d46613217565b60009182526020822060059091020180549092508290611d6890600190613243565b81548110611d7857611d78613217565b60009182526020909120600c90910201805460049091015414949350505050565b6000546001600160a01b03163314611dc35760405162461bcd60e51b8152600401610808906135f1565b6000836001600160a01b03168383604051611dde9190613633565b60006040518083038185875af1925050503d8060008114611e1b576040519150601f19603f3d011682016040523d82523d6000602084013e611e20565b606091505b5050905080611e655760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610808565b50505050565b600086815260036020526040902054600280548892908110611e8f57611e8f613217565b600091825260209091206002600590920201015460ff1615611ec35760405162461bcd60e51b8152600401610808906133cb565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f319190613282565b5090935060029250611f41915050565b816004811115611f5357611f536132e9565b14611fae5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610808565b85611ff05760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610808565b60008881526003602052604081205460028054909190811061201457612014613217565b90600052602060002090600502019050806001015486111561206f5760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610808565b8054600090829061208290600190613243565b8154811061209257612092613217565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600c9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121119190613282565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa15801561216c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612190919061364f565b505050505091505060005b8a81101561240d5733848d8d848181106121b7576121b7613217565b90506020020135815481106121ce576121ce613217565b60009182526020909120600490910201546001600160a01b0316146122055760405162461bcd60e51b81526004016108089061354b565b811580612279575089888a604051602001612222939291906136b9565b60405160208183030381529060405280519060200120846000018d8d8481811061224e5761224e613217565b905060200201358154811061226557612265613217565b906000526020600020906004020160010154145b6122eb5760405162461bcd60e51b815260206004820152603d60248201527f54686520636f6d6d6974206d757374206d61746368207468652063686f69636560448201527f20696e20636f7572747320776974682068696464656e20766f7465732e0000006064820152608401610808565b838c8c838181106122fe576122fe613217565b905060200201358154811061231557612315613217565b600091825260209091206003600490920201015460ff161561236e5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610808565b89848d8d8481811061238257612382613217565b905060200201358154811061239957612399613217565b60009182526020909120600260049092020101556001848d8d848181106123c2576123c2613217565b90506020020135815481106123d9576123d9613217565b60009182526020909120600490910201600301805460ff19169115159190911790558061240581613582565b91505061219b565b508a8a90508360040160008282546124259190613374565b90915550506000898152600284016020526040812080548c929061244a908490613374565b90915550506001830154890361247957600383015460ff16156124745760038301805460ff191690555b6124f2565b60018301546000908152600284016020526040808220548b8352912054036124bb57600383015460ff166124745760038301805460ff191660011790556124f2565b60018301546000908152600284016020526040808220548b835291205411156124f2576001830189905560038301805460ff191690555b88336001600160a01b03168d7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48e8e8c604051612531939291906136e6565b60405180910390a4505050505050505050505050565b6000546001600160a01b031633146125715760405162461bcd60e51b8152600401610808906135f1565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b0316837f39935cf45244bc296a03d6aef1cf17779033ee27090ce9c68d432367ce10699684846040516125cf92919061373f565b60405180910390a3505050565b60008060008060006002600360008a8152602001908152602001600020548154811061260a5761260a613217565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061263e5761263e613217565b90600052602060002090600c0201600001878154811061266057612660613217565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146126cc5760405162461bcd60e51b815260040161080890613387565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad2016127578587836137aa565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156127ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d29190613443565b6127dc9190613243565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600c909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612865908a908a908a9061386a565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061289b5761289b613217565b600091825260208083208784526003600590930201918201905260408220548154919350839181106128cf576128cf613217565b90600052602060002090600c020160000184815481106128f1576128f1613217565b600091825260209091206004909102016003015460ff169695505050505050565b60008281526003602052604081205460028054839290811061293657612936613217565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061296a5761296a613217565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600c93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156129c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ed91906132ff565b5091509150826004015460001480612a1c575080158015612a1c57506000828152600284016020526040902054155b15612a2e576000945050505050612a5f565b8015612a43575050600401549150612a5f9050565b506000908152600290910160205260409020549150612a5f9050565b92915050565b6000546001600160a01b03163314612a8f5760405162461bcd60e51b8152600401610808906135f1565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b239190613282565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba69190613443565b612bb09190613243565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015612bf1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c19919081019061388f565b5050600154604051631a383be960e31b81526001600160a01b038e811660048301526001600160601b038d166024830152989a50600099508998909116965063d1c1df4895506044019350612c6d92505050565b606060405180830381865afa158015612c8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cae91906139a8565b50600154604051630fad06e960e11b81526001600160601b03881660048201529294509092506000916001600160a01b0390911690631f5a0dd29060240160e060405180830381865afa158015612d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2d919061364f565b50505050925050508382612d419190613374565b8310158015612d505750808310155b98975050505050505050565b600060208284031215612d6e57600080fd5b5035919050565b6001600160a01b0381168114612d8a57600080fd5b50565b60008060008060808587031215612da357600080fd5b843593506020850135612db581612d75565b93969395505050506040820135916060013590565b60008060408385031215612ddd57600080fd5b50508035926020909101359150565b600080600060608486031215612e0157600080fd5b505081359360208301359350604090920135919050565b60005b83811015612e33578181015183820152602001612e1b565b50506000910152565b60008151808452612e54816020860160208601612e18565b601f01601f19169290920160200192915050565b8381528215156020820152606060408201526000612e896060830184612e3c565b95945050505050565b60008083601f840112612ea457600080fd5b5081356001600160401b03811115612ebb57600080fd5b6020830191508360208260051b8501011115612ed657600080fd5b9250929050565b60008060008060608587031215612ef357600080fd5b8435935060208501356001600160401b03811115612f1057600080fd5b612f1c87828801612e92565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015612f6757835183529284019291840191600101612f4b565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612fb157612fb1612f73565b604052919050565b60006001600160401b03831115612fd257612fd2612f73565b612fe5601f8401601f1916602001612f89565b9050828152838383011115612ff957600080fd5b828260208301376000602084830101529392505050565b60008060006060848603121561302557600080fd5b833561303081612d75565b92506020840135915060408401356001600160401b0381111561305257600080fd5b8401601f8101861361306357600080fd5b61307286823560208401612fb9565b9150509250925092565b60008060008060008060a0878903121561309557600080fd5b8635955060208701356001600160401b03808211156130b357600080fd5b6130bf8a838b01612e92565b9097509550604089013594506060890135935060808901359150808211156130e657600080fd5b508701601f810189136130f857600080fd5b61310789823560208401612fb9565b9150509295509295509295565b60006020828403121561312657600080fd5b81356117cc81612d75565b60008083601f84011261314357600080fd5b5081356001600160401b0381111561315a57600080fd5b602083019150836020828501011115612ed657600080fd5b60008060006040848603121561318757600080fd5b8335925060208401356001600160401b038111156131a457600080fd5b6131b086828701613131565b9497909650939450505050565b6000806000806000608086880312156131d557600080fd5b853594506020860135935060408601356001600160401b038111156131f957600080fd5b61320588828901613131565b96999598509660600135949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612a5f57612a5f61322d565b80516001600160601b038116811461326d57600080fd5b919050565b8051801515811461326d57600080fd5b600080600080600060a0868803121561329a57600080fd5b6132a386613256565b945060208601516132b381612d75565b6040870151909450600581106132c857600080fd5b92506132d660608701613272565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b60008060006060848603121561331457600080fd5b8351925061332460208501613272565b915061333260408501613272565b90509250925092565b8082028115828204841417612a5f57612a5f61322d565b60008261336f57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115612a5f57612a5f61322d565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b60006020828403121561341457600080fd5b81516117cc81612d75565b6000806040838503121561343257600080fd5b505080516020909101519092909150565b60006020828403121561345557600080fd5b5051919050565b60006020828403121561346e57600080fd5b6117cc82613272565b600181811c9082168061348b57607f821691505b6020821081036134ab57634e487b7160e01b600052602260045260246000fd5b50919050565b83815260006020848184015260606040840152600084546134d181613477565b80606087015260806001808416600081146134f3576001811461350d5761353b565b60ff1985168984015283151560051b89018301955061353b565b896000528660002060005b858110156135335781548b8201860152908301908801613518565b8a0184019650505b50939a9950505050505050505050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6000600182016135945761359461322d565b5060010190565b81835260006001600160fb1b038311156135b457600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006135e160408301858761359b565b9050826020830152949350505050565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60008251613645818460208701612e18565b9190910192915050565b600080600080600080600060e0888a03121561366a57600080fd5b61367388613256565b965061368160208901613272565b955060408801519450606088015193506080880151925060a088015191506136ab60c08901613272565b905092959891949750929550565b838152600083516136d1816020850160208801612e18565b60209201918201929092526040019392505050565b6040815260006136fa60408301858761359b565b828103602084015261370c8185612e3c565b9695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000613753602083018486613716565b949350505050565b601f8211156137a557600081815260208120601f850160051c810160208610156137825750805b601f850160051c820191505b818110156137a15782815560010161378e565b5050505b505050565b6001600160401b038311156137c1576137c1612f73565b6137d5836137cf8354613477565b8361375b565b6000601f84116001811461380957600085156137f15750838201355b600019600387901b1c1916600186901b178355613863565b600083815260209020601f19861690835b8281101561383a578685013582556020948501946001909201910161381a565b50868210156138575760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b838152604060208201526000612e89604083018486613716565b805161326d81612d75565b6000806000806000806000806000806101408b8d0312156138af57600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b01516001600160401b03808211156138f057600080fd5b818d0191508d601f83011261390457600080fd5b81518181111561391657613916612f73565b61392560208260051b01612f89565b91508181835260208301925060208260051b85010191508f82111561394957600080fd5b6020840193505b8184101561397457835161396381612d75565b835260209384019390920191613950565b8097505050505060e08b015192506101008b015191506139976101208c01613884565b90509295989b9194979a5092959850565b6000806000606084860312156139bd57600080fd5b835192506020840151915060408401519050925092509256fea26469706673582212201f237456c00fa4bb2bdc69a9c8b4d23ff3985d9bd704ad06a128920c9811e32864736f6c63430008120033", - "deployedBytecode": "0x60806040526004361061016c5760003560e01c8063751accd0116100cc578063b6ede5401161007a578063b6ede540146104ac578063ba66fde7146104cc578063be467604146104ec578063da3beb8c14610502578063e349ad30146103d4578063e4c0aaf414610522578063f2f4eb261461054257600080fd5b8063751accd0146103b4578063796490f9146103d45780637c04034e146103ea5780638e4264601461040a578063a6a7f0eb1461042a578063a7cc08fe1461044a578063b34bfaa81461049657600080fd5b80634b2f0ea0116101295780634b2f0ea0146102965780634fe264fb146102ab578063564a565d146102cb5780635c92e2f6146102fa57806365540b961461031a57806369f3f041146103475780636d4cd8ea1461039457600080fd5b80630baa64d1146101715780630c340a24146101a65780631200aabc146101de5780631c3db16d14610219578063362c3479146102565780633b30414714610276575b600080fd5b34801561017d57600080fd5b5061019161018c366004612d5c565b610562565b60405190151581526020015b60405180910390f35b3480156101b257600080fd5b506000546101c6906001600160a01b031681565b6040516001600160a01b03909116815260200161019d565b3480156101ea57600080fd5b5061020b6101f9366004612d5c565b60036020526000908152604090205481565b60405190815260200161019d565b34801561022557600080fd5b50610239610234366004612d5c565b6105d9565b60408051938452911515602084015215159082015260600161019d565b34801561026257600080fd5b5061020b610271366004612d8d565b610747565b34801561028257600080fd5b506101c6610291366004612d5c565b610b1d565b6102a96102a4366004612dca565b610e29565b005b3480156102b757600080fd5b5061020b6102c6366004612dec565b611690565b3480156102d757600080fd5b506102eb6102e6366004612d5c565b6117d3565b60405161019d93929190612e68565b34801561030657600080fd5b506102a9610315366004612edd565b611899565b34801561032657600080fd5b5061033a610335366004612d5c565b611ba6565b60405161019d9190612f2f565b34801561035357600080fd5b50610367610362366004612dec565b611c6a565b604080519687529415156020870152938501929092526060840152608083015260a082015260c00161019d565b3480156103a057600080fd5b506101916103af366004612d5c565b611d22565b3480156103c057600080fd5b506102a96103cf366004613010565b611d99565b3480156103e057600080fd5b5061020b61271081565b3480156103f657600080fd5b506102a961040536600461307c565b611e6b565b34801561041657600080fd5b506102a9610425366004613114565b612547565b34801561043657600080fd5b506102a9610445366004613172565b612593565b34801561045657600080fd5b5061046a610465366004612dec565b6125dc565b604080516001600160a01b0390951685526020850193909352918301521515606082015260800161019d565b3480156104a257600080fd5b5061020b614e2081565b3480156104b857600080fd5b506102a96104c73660046131bd565b6126a2565b3480156104d857600080fd5b506101916104e7366004612dec565b612877565b3480156104f857600080fd5b5061020b61138881565b34801561050e57600080fd5b5061020b61051d366004612dca565b612912565b34801561052e57600080fd5b506102a961053d366004613114565b612a65565b34801561054e57600080fd5b506001546101c6906001600160a01b031681565b60008181526003602052604081205460028054839290811061058657610586613217565b600091825260208220600590910201805490925082906105a890600190613243565b815481106105b8576105b8613217565b60009182526020909120600c90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061060557610605613217565b6000918252602082206005909102018054909250829061062790600190613243565b8154811061063757610637613217565b60009182526020909120600c90910201600381015460ff169450905083610662578060010154610665565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156106b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d89190613282565b50909350600492506106e8915050565b8160048111156106fa576106fa6132e9565b0361073d57600061070a88611ba6565b9050805160010361073b578060008151811061072857610728613217565b6020026020010151965060009550600194505b505b5050509193909250565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190613282565b509350505050806108115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b60008681526003602052604081205460028054909190811061083557610835613217565b6000918252602080832088845260036005909302019182019052604082205481549193508391811061086957610869613217565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600c9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa1580156108c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e891906132ff565b5050600087815260078401602052604090205490915060ff16610932576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610a77565b8086036109a75760008681526006830160205260409020546109555760006109a0565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610996919061333b565b6109a09190613352565b9450610a77565b600081815260078301602052604090205460ff16610a775781600601600083600a016001815481106109db576109db613217565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610a1157610a11613217565b9060005260206000200154815260200190815260200160002054610a359190613374565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610a6a919061333b565b610a749190613352565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610b11576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b6001546000906001600160a01b03163314610b4a5760405162461bcd60e51b815260040161080890613387565b600082815260036020526040902054600280548492908110610b6e57610b6e613217565b600091825260209091206002600590920201015460ff1615610ba25760405162461bcd60e51b8152600401610808906133cb565b600083815260036020526040812054600280549091908110610bc657610bc6613217565b60009182526020822060059091020180549092508290610be890600190613243565b81548110610bf857610bf8613217565b90600052602060002090600c020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c819190613402565b60015460405163564a565d60e01b8152600481018990529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf49190613282565b50508554604051632638506b60e11b81526001600160601b03851660048201819052602482018d90526044820192909252939450926001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190613402565b9650610d8c8888612ab1565b15610e1957604080516080810182526001600160a01b03898116825260006020808401828152948401828152606085018381528a5460018082018d558c8652939094209551600490940290950180546001600160a01b0319169390941692909217835593519382019390935591516002830155516003909101805460ff1916911515919091179055610e1e565b600096505b505050505050919050565b600082815260036020526040902054600280548492908110610e4d57610e4d613217565b600091825260209091206002600590920201015460ff1615610e815760405162461bcd60e51b8152600401610808906133cb565b600083815260036020526040812054600280549091908110610ea557610ea5613217565b906000526020600020906005020190508060010154831115610f095760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610808565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7a919061341f565b91509150814210158015610f8d57508042105b610fd25760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610808565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611013573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103791906132ff565b5050905086810361104c5761271091506110cd565b61271061138861105c8686613243565b611066919061333b565b6110709190613352565b61107a8542613243565b106110c75760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610808565b614e2091505b845460009086906110e090600190613243565b815481106110f0576110f0613217565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600c949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111739190613443565b61117d9190613243565b60008a815260078401602052604090205490915060ff16156111e15760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610808565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561122b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124f9190613443565b90506000612710611260878461333b565b61126a9190613352565b6112749083613374565b60008c8152600686016020526040812054919250908211156113255760008c815260068601602052604090205434906112ad9084613243565b116112d25760008c81526006860160205260409020546112cd9083613243565b6112d4565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161131c929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611351908490613374565b909155505060008c815260068601602052604081208054839290611376908490613374565b909155505060008c815260068601602052604090205482116114485760008c8152600686016020526040812054600987018054919290916113b8908490613374565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611653578285600901546114659190613243565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa1580156114b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d7919061345c565b156114f05760028a01805460ff191660011790556115d3565b895460038b016000611503876001613374565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600c02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161157e91815260200190565b602060405180830381865afa15801561159b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bf9190613443565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b8152600401611620939291906134b1565b6000604051808303818588803b15801561163957600080fd5b505af115801561164d573d6000803e3d6000fd5b50505050505b8034111561168157336108fc6116698334613243565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b6000838152600360205260408120546002805483929081106116b4576116b4613217565b600091825260208083208784526003600590930201918201905260408220548154919350839181106116e8576116e8613217565b90600052602060002090600c0201600001848154811061170a5761170a613217565b600091825260208220600154604051631c3db16d60e01b815260048082018c905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178c91906132ff565b506003850154919350915060ff1680156117b0575081836002015414806117b05750805b156117c3576127109450505050506117cc565b60009450505050505b9392505050565b600281815481106117e357600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff909116929161181690613477565b80601f016020809104026020016040519081016040528092919081815260200182805461184290613477565b801561188f5780601f106118645761010080835404028352916020019161188f565b820191906000526020600020905b81548152906001019060200180831161187257829003601f168201915b5050505050905083565b6000848152600360205260409020546002805486929081106118bd576118bd613217565b600091825260209091206002600590920201015460ff16156118f15760405162461bcd60e51b8152600401610808906133cb565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa15801561193b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195f9190613282565b509093506001925061196f915050565b816004811115611981576119816132e9565b146119de5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610808565b82611a1b5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610808565b600086815260036020526040812054600280549091908110611a3f57611a3f613217565b60009182526020822060059091020180549092508290611a6190600190613243565b81548110611a7157611a71613217565b90600052602060002090600c0201905060005b86811015611b3f573382898984818110611aa057611aa0613217565b9050602002013581548110611ab757611ab7613217565b60009182526020909120600490910201546001600160a01b031614611aee5760405162461bcd60e51b81526004016108089061354b565b8582898984818110611b0257611b02613217565b9050602002013581548110611b1957611b19613217565b600091825260209091206001600490920201015580611b3781613582565b915050611a84565b5086869050816005016000828254611b579190613374565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611b94908b908b908b906135cd565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611bcc57611bcc613217565b60009182526020822060059091020180549092508290611bee90600190613243565b81548110611bfe57611bfe613217565b90600052602060002090600c0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c5c57602002820191906000526020600020905b815481526020019060010190808311611c48575b505050505092505050919050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611c9b57611c9b613217565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611ccf57611ccf613217565b600091825260208083206001600c909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611d4657611d46613217565b60009182526020822060059091020180549092508290611d6890600190613243565b81548110611d7857611d78613217565b60009182526020909120600c90910201805460049091015414949350505050565b6000546001600160a01b03163314611dc35760405162461bcd60e51b8152600401610808906135f1565b6000836001600160a01b03168383604051611dde9190613633565b60006040518083038185875af1925050503d8060008114611e1b576040519150601f19603f3d011682016040523d82523d6000602084013e611e20565b606091505b5050905080611e655760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610808565b50505050565b600086815260036020526040902054600280548892908110611e8f57611e8f613217565b600091825260209091206002600590920201015460ff1615611ec35760405162461bcd60e51b8152600401610808906133cb565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f319190613282565b5090935060029250611f41915050565b816004811115611f5357611f536132e9565b14611fae5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610808565b85611ff05760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610808565b60008881526003602052604081205460028054909190811061201457612014613217565b90600052602060002090600502019050806001015486111561206f5760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610808565b8054600090829061208290600190613243565b8154811061209257612092613217565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600c9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121119190613282565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa15801561216c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612190919061364f565b505050505091505060005b8a81101561240d5733848d8d848181106121b7576121b7613217565b90506020020135815481106121ce576121ce613217565b60009182526020909120600490910201546001600160a01b0316146122055760405162461bcd60e51b81526004016108089061354b565b811580612279575089888a604051602001612222939291906136b9565b60405160208183030381529060405280519060200120846000018d8d8481811061224e5761224e613217565b905060200201358154811061226557612265613217565b906000526020600020906004020160010154145b6122eb5760405162461bcd60e51b815260206004820152603d60248201527f54686520636f6d6d6974206d757374206d61746368207468652063686f69636560448201527f20696e20636f7572747320776974682068696464656e20766f7465732e0000006064820152608401610808565b838c8c838181106122fe576122fe613217565b905060200201358154811061231557612315613217565b600091825260209091206003600490920201015460ff161561236e5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610808565b89848d8d8481811061238257612382613217565b905060200201358154811061239957612399613217565b60009182526020909120600260049092020101556001848d8d848181106123c2576123c2613217565b90506020020135815481106123d9576123d9613217565b60009182526020909120600490910201600301805460ff19169115159190911790558061240581613582565b91505061219b565b508a8a90508360040160008282546124259190613374565b90915550506000898152600284016020526040812080548c929061244a908490613374565b90915550506001830154890361247957600383015460ff16156124745760038301805460ff191690555b6124f2565b60018301546000908152600284016020526040808220548b8352912054036124bb57600383015460ff166124745760038301805460ff191660011790556124f2565b60018301546000908152600284016020526040808220548b835291205411156124f2576001830189905560038301805460ff191690555b88336001600160a01b03168d7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48e8e8c604051612531939291906136e6565b60405180910390a4505050505050505050505050565b6000546001600160a01b031633146125715760405162461bcd60e51b8152600401610808906135f1565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b0316837f39935cf45244bc296a03d6aef1cf17779033ee27090ce9c68d432367ce10699684846040516125cf92919061373f565b60405180910390a3505050565b60008060008060006002600360008a8152602001908152602001600020548154811061260a5761260a613217565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061263e5761263e613217565b90600052602060002090600c0201600001878154811061266057612660613217565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146126cc5760405162461bcd60e51b815260040161080890613387565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad2016127578587836137aa565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156127ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d29190613443565b6127dc9190613243565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600c909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612865908a908a908a9061386a565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061289b5761289b613217565b600091825260208083208784526003600590930201918201905260408220548154919350839181106128cf576128cf613217565b90600052602060002090600c020160000184815481106128f1576128f1613217565b600091825260209091206004909102016003015460ff169695505050505050565b60008281526003602052604081205460028054839290811061293657612936613217565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061296a5761296a613217565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600c93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156129c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ed91906132ff565b5091509150826004015460001480612a1c575080158015612a1c57506000828152600284016020526040902054155b15612a2e576000945050505050612a5f565b8015612a43575050600401549150612a5f9050565b506000908152600290910160205260409020549150612a5f9050565b92915050565b6000546001600160a01b03163314612a8f5760405162461bcd60e51b8152600401610808906135f1565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b239190613282565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba69190613443565b612bb09190613243565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015612bf1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c19919081019061388f565b5050600154604051631a383be960e31b81526001600160a01b038e811660048301526001600160601b038d166024830152989a50600099508998909116965063d1c1df4895506044019350612c6d92505050565b606060405180830381865afa158015612c8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cae91906139a8565b50600154604051630fad06e960e11b81526001600160601b03881660048201529294509092506000916001600160a01b0390911690631f5a0dd29060240160e060405180830381865afa158015612d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2d919061364f565b50505050925050508382612d419190613374565b8310158015612d505750808310155b98975050505050505050565b600060208284031215612d6e57600080fd5b5035919050565b6001600160a01b0381168114612d8a57600080fd5b50565b60008060008060808587031215612da357600080fd5b843593506020850135612db581612d75565b93969395505050506040820135916060013590565b60008060408385031215612ddd57600080fd5b50508035926020909101359150565b600080600060608486031215612e0157600080fd5b505081359360208301359350604090920135919050565b60005b83811015612e33578181015183820152602001612e1b565b50506000910152565b60008151808452612e54816020860160208601612e18565b601f01601f19169290920160200192915050565b8381528215156020820152606060408201526000612e896060830184612e3c565b95945050505050565b60008083601f840112612ea457600080fd5b5081356001600160401b03811115612ebb57600080fd5b6020830191508360208260051b8501011115612ed657600080fd5b9250929050565b60008060008060608587031215612ef357600080fd5b8435935060208501356001600160401b03811115612f1057600080fd5b612f1c87828801612e92565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015612f6757835183529284019291840191600101612f4b565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612fb157612fb1612f73565b604052919050565b60006001600160401b03831115612fd257612fd2612f73565b612fe5601f8401601f1916602001612f89565b9050828152838383011115612ff957600080fd5b828260208301376000602084830101529392505050565b60008060006060848603121561302557600080fd5b833561303081612d75565b92506020840135915060408401356001600160401b0381111561305257600080fd5b8401601f8101861361306357600080fd5b61307286823560208401612fb9565b9150509250925092565b60008060008060008060a0878903121561309557600080fd5b8635955060208701356001600160401b03808211156130b357600080fd5b6130bf8a838b01612e92565b9097509550604089013594506060890135935060808901359150808211156130e657600080fd5b508701601f810189136130f857600080fd5b61310789823560208401612fb9565b9150509295509295509295565b60006020828403121561312657600080fd5b81356117cc81612d75565b60008083601f84011261314357600080fd5b5081356001600160401b0381111561315a57600080fd5b602083019150836020828501011115612ed657600080fd5b60008060006040848603121561318757600080fd5b8335925060208401356001600160401b038111156131a457600080fd5b6131b086828701613131565b9497909650939450505050565b6000806000806000608086880312156131d557600080fd5b853594506020860135935060408601356001600160401b038111156131f957600080fd5b61320588828901613131565b96999598509660600135949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612a5f57612a5f61322d565b80516001600160601b038116811461326d57600080fd5b919050565b8051801515811461326d57600080fd5b600080600080600060a0868803121561329a57600080fd5b6132a386613256565b945060208601516132b381612d75565b6040870151909450600581106132c857600080fd5b92506132d660608701613272565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b60008060006060848603121561331457600080fd5b8351925061332460208501613272565b915061333260408501613272565b90509250925092565b8082028115828204841417612a5f57612a5f61322d565b60008261336f57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115612a5f57612a5f61322d565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b60006020828403121561341457600080fd5b81516117cc81612d75565b6000806040838503121561343257600080fd5b505080516020909101519092909150565b60006020828403121561345557600080fd5b5051919050565b60006020828403121561346e57600080fd5b6117cc82613272565b600181811c9082168061348b57607f821691505b6020821081036134ab57634e487b7160e01b600052602260045260246000fd5b50919050565b83815260006020848184015260606040840152600084546134d181613477565b80606087015260806001808416600081146134f3576001811461350d5761353b565b60ff1985168984015283151560051b89018301955061353b565b896000528660002060005b858110156135335781548b8201860152908301908801613518565b8a0184019650505b50939a9950505050505050505050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6000600182016135945761359461322d565b5060010190565b81835260006001600160fb1b038311156135b457600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006135e160408301858761359b565b9050826020830152949350505050565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60008251613645818460208701612e18565b9190910192915050565b600080600080600080600060e0888a03121561366a57600080fd5b61367388613256565b965061368160208901613272565b955060408801519450606088015193506080880151925060a088015191506136ab60c08901613272565b905092959891949750929550565b838152600083516136d1816020850160208801612e18565b60209201918201929092526040019392505050565b6040815260006136fa60408301858761359b565b828103602084015261370c8185612e3c565b9695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000613753602083018486613716565b949350505050565b601f8211156137a557600081815260208120601f850160051c810160208610156137825750805b601f850160051c820191505b818110156137a15782815560010161378e565b5050505b505050565b6001600160401b038311156137c1576137c1612f73565b6137d5836137cf8354613477565b8361375b565b6000601f84116001811461380957600085156137f15750838201355b600019600387901b1c1916600186901b178355613863565b600083815260209020601f19861690835b8281101561383a578685013582556020948501946001909201910161381a565b50868210156138575760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b838152604060208201526000612e89604083018486613716565b805161326d81612d75565b6000806000806000806000806000806101408b8d0312156138af57600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b01516001600160401b03808211156138f057600080fd5b818d0191508d601f83011261390457600080fd5b81518181111561391657613916612f73565b61392560208260051b01612f89565b91508181835260208301925060208260051b85010191508f82111561394957600080fd5b6020840193505b8184101561397457835161396381612d75565b835260209384019390920191613950565b8097505050505060e08b015192506101008b015191506139976101208c01613884565b90509295989b9194979a5092959850565b6000806000606084860312156139bd57600080fd5b835192506020840151915060408401519050925092509256fea26469706673582212201f237456c00fa4bb2bdc69a9c8b4d23ff3985d9bd704ad06a128920c9811e32864736f6c63430008120033", + "numDeployments": 5, + "solcInputHash": "2049fd55b43646f24967ea776592ce82", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"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\":true,\"internalType\":\"uint256\",\"name\":\"_externalDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_party\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"Evidence\",\"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\"}],\"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\"}],\"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\":\"_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\":[{\"internalType\":\"uint256\",\"name\":\"_externalDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_evidence\",\"type\":\"string\"}],\"name\":\"submitEvidence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":{\"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.\"}},\"Evidence(uint256,address,string)\":{\"details\":\"To be raised when evidence is submitted. Should point to the resource (evidences are not to be stored on chain due to gas considerations).\",\"params\":{\"_evidence\":\"IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'\",\"_externalDisputeID\":\"Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right external dispute ID.\",\"_party\":\"The address of the party submiting the evidence. Note that 0x0 refers to evidence not submitted by any party.\"}},\"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\":{\"details\":\"Constructor.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"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)\":{\"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.\"},\"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)\":{\"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.\"}},\"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.\"}},\"submitEvidence(uint256,string)\":{\"details\":\"Submits evidence for a dispute.\",\"params\":{\"_evidence\":\"IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'.\",\"_externalDisputeID\":\"Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right evidence group ID.\"}},\"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.\",\"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.\"}}},\"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\":{\"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 v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\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 amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` 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 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport \\\"./interfaces/IDisputeKit.sol\\\";\\nimport \\\"./interfaces/ISortitionModule.sol\\\";\\nimport \\\"../libraries/SafeERC20.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 IArbitratorV2 {\\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 => bool) supportedDisputeKits; // True if DK with this ID is supported by the court.\\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 }\\n\\n struct Juror {\\n uint96[] courtIDs; // The IDs of courts where the juror's stake path ends. A stake path is a path from the general court to a court the juror directly staked in using `_setStake`.\\n mapping(uint96 => uint256) stakedPnk; // The amount of PNKs the juror has staked in the court in the form `stakedPnk[courtID]`.\\n mapping(uint96 => uint256) lockedPnk; // The amount of PNKs the juror has locked in the court in the form `lockedPnk[courtID]`.\\n }\\n\\n struct DisputeKitNode {\\n uint256 parent; // Index of the parent dispute kit. If it's 0 then this DK is a root.\\n uint256[] children; // List of child dispute kits.\\n IDisputeKit disputeKit; // The dispute kit implementation.\\n uint256 depthLevel; // How far this DK is from the root. 0 for root DK.\\n bool disabled; // True if the dispute kit is disabled and can't be used. This parameter is added preemptively to avoid storage changes in the future.\\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 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 uint96 public constant FORKING_COURT = 0; // Index of the forking court.\\n uint96 public constant GENERAL_COURT = 1; // Index of the default (general) court.\\n uint256 public constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent.\\n uint256 public constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n uint256 public constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\n uint256 public constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 public constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n uint256 public constant SEARCH_ITERATIONS = 10; // Number of iterations to search for suitable parent court before jumping to the top court.\\n IERC20 public constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\n address public governor; // The governor of the contract.\\n IERC20 public pinakion; // The Pinakion token contract.\\n // TODO: interactions with jurorProsecutionModule.\\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 DisputeKitNode[] public disputeKitNodes; // The list of DisputeKitNode, indexed by DisputeKitID.\\n Dispute[] public disputes; // The disputes.\\n mapping(address => Juror) internal jurors; // The jurors.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event StakeSet(address indexed _address, uint256 _courtID, uint256 _amount);\\n event StakeDelayed(address indexed _address, uint256 _courtID, uint256 _amount, uint256 _penalty);\\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 uint256 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(\\n uint256 indexed _disputeKitID,\\n IDisputeKit indexed _disputeKitAddress,\\n uint256 indexed _parent\\n );\\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\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n /// @dev Constructor.\\n /// @param _governor The governor'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 constructor(\\n address _governor,\\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 ) {\\n governor = _governor;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a node has no parent.\\n disputeKitNodes.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKitNodes.push(\\n DisputeKitNode({\\n parent: NULL_DISPUTE_KIT,\\n children: new uint256[](0),\\n disputeKit: _disputeKit,\\n depthLevel: 0,\\n disabled: false\\n })\\n );\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit, NULL_DISPUTE_KIT);\\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 emit CourtCreated(\\n 1,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n new uint256[](0)\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\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 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 `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 /// @param _parent The ID of the parent dispute kit. It is left empty when root DK is created.\\n /// Note that the root DK must be supported by the general court.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress, uint256 _parent) external onlyByGovernor {\\n uint256 disputeKitID = disputeKitNodes.length;\\n if (_parent >= disputeKitID) revert InvalidDisputKitParent();\\n uint256 depthLevel;\\n if (_parent != NULL_DISPUTE_KIT) {\\n depthLevel = disputeKitNodes[_parent].depthLevel + 1;\\n // It should be always possible to reach the root from the leaf with the defined number of search iterations.\\n if (depthLevel >= SEARCH_ITERATIONS) revert DepthLevelMax();\\n }\\n disputeKitNodes.push(\\n DisputeKitNode({\\n parent: _parent,\\n children: new uint256[](0),\\n disputeKit: _disputeKitAddress,\\n depthLevel: depthLevel,\\n disabled: false\\n })\\n );\\n\\n disputeKitNodes[_parent].children.push(disputeKitID);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress, _parent);\\n if (_parent == NULL_DISPUTE_KIT) {\\n // A new dispute kit tree root should always be supported by the General court.\\n _enableDisputeKit(GENERAL_COURT, disputeKitID, true);\\n }\\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] >= disputeKitNodes.length) {\\n revert WrongDisputeKitIndex();\\n }\\n court.supportedDisputeKits[_supportedDisputeKits[i]] = true;\\n }\\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 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 if (_courtID != GENERAL_COURT && courts[courts[_courtID].parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < courts[_courtID].children.length; i++) {\\n if (courts[courts[_courtID].children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n courts[_courtID].minStake = _minStake;\\n courts[_courtID].hiddenVotes = _hiddenVotes;\\n courts[_courtID].alpha = _alpha;\\n courts[_courtID].feeForJuror = _feeForJuror;\\n courts[_courtID].jurorsForCourtJump = _jurorsForCourtJump;\\n courts[_courtID].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] >= disputeKitNodes.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n if (_courtID == GENERAL_COURT && disputeKitNodes[_disputeKitIDs[i]].parent == NULL_DISPUTE_KIT) {\\n revert CannotDisableRootDKInGeneral();\\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 CurrencyRate storage rate = currencyRates[_feeToken];\\n rate.rateInEth = _rateInEth;\\n rate.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 _stake The new stake.\\n function setStake(uint96 _courtID, uint256 _stake) external {\\n if (!_setStakeForAccount(msg.sender, _courtID, _stake, 0)) revert StakingFailed();\\n }\\n\\n function setStakeBySortitionModule(address _account, uint96 _courtID, uint256 _stake, uint256 _penalty) external {\\n if (msg.sender != address(sortitionModule)) revert WrongCaller();\\n _setStakeForAccount(_account, _courtID, _stake, _penalty);\\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 require(_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount), \\\"Transfer failed\\\");\\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 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 = disputeKitNodes[disputeKitID].disputeKit;\\n Court storage court = courts[dispute.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 !disputeKitNodes[round.disputeKitID].disputeKit.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 !disputeKitNodes[round.disputeKitID].disputeKit.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 = disputeKitNodes[round.disputeKitID].disputeKit;\\n\\n uint256 startIndex = round.drawnJurors.length;\\n uint256 endIndex = startIndex + _iterations <= round.nbVotes ? startIndex + _iterations : round.nbVotes;\\n\\n for (uint256 i = startIndex; i < endIndex; i++) {\\n address drawnAddress = disputeKit.draw(_disputeID);\\n if (drawnAddress != address(0)) {\\n jurors[drawnAddress].lockedPnk[dispute.courtID] += round.pnkAtStakePerJuror;\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n }\\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(disputeKitNodes[round.disputeKitID].disputeKit)) 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 for (uint256 i = 0; i < SEARCH_ITERATIONS; i++) {\\n if (courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n break;\\n } else if (disputeKitNodes[newDisputeKitID].parent != NULL_DISPUTE_KIT) {\\n newDisputeKitID = disputeKitNodes[newDisputeKitID].parent;\\n } else {\\n // DK's parent has 0 index, that means we reached the root DK (0 depth level).\\n // Jump to the next parent court if the current court doesn't support any DK from this tree.\\n // Note that we don't reset newDisputeKitID in this case as, a precaution.\\n newCourtID = courts[newCourtID].parent;\\n }\\n }\\n // We didn't find a court that is compatible with DK from this tree, so we jump directly to the top court.\\n // Note that this can only happen when disputeKitID is at its root, and each root DK is supported by the top court by default.\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n newCourtID = GENERAL_COURT;\\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 IDisputeKit disputeKit = disputeKitNodes[extraRound.disputeKitID].disputeKit;\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKit.createDispute(_disputeID, _numberOfChoices, _extraData, extraRound.nbVotes);\\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 /// @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 {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n Round storage round = dispute.rounds[_round];\\n IDisputeKit disputeKit = disputeKitNodes[round.disputeKitID].disputeKit;\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRoundCache = round.pnkPenalties; // For saving gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\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 pnkPenaltiesInRoundCache = _executePenalties(\\n ExecuteParams(_disputeID, _round, coherentCount, numberOfVotesInRound, pnkPenaltiesInRoundCache, i)\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams(_disputeID, _round, coherentCount, numberOfVotesInRound, pnkPenaltiesInRoundCache, i)\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRoundCache) {\\n round.pnkPenalties = pnkPenaltiesInRoundCache; // 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 = disputeKitNodes[round.disputeKitID].disputeKit;\\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 );\\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 jurors[account].lockedPnk[dispute.courtID] -= penalty;\\n\\n // Apply the penalty to the staked PNKs\\n if (jurors[account].stakedPnk[dispute.courtID] >= courts[dispute.courtID].minStake + penalty) {\\n // The juror still has enough staked PNKs after penalty for this court.\\n uint256 newStake = jurors[account].stakedPnk[dispute.courtID] - penalty;\\n _setStakeForAccount(account, dispute.courtID, newStake, penalty);\\n } else if (jurors[account].stakedPnk[dispute.courtID] != 0) {\\n // The juror does not have enough staked PNKs after penalty for this court, unstake them.\\n _setStakeForAccount(account, dispute.courtID, 0, penalty);\\n }\\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 = disputeKitNodes[round.disputeKitID].disputeKit;\\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 );\\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 jurors[account].lockedPnk[dispute.courtID] -= pnkLocked;\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (jurors[account].stakedPnk[dispute.courtID] == 0) {\\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 = disputeKitNodes[round.disputeKitID].disputeKit;\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(\\n uint256 _disputeID,\\n uint256 _round\\n )\\n external\\n view\\n returns (\\n uint256 disputeKitID,\\n uint256 pnkAtStakePerJuror,\\n uint256 totalFeesForJurors,\\n uint256 nbVotes,\\n uint256 repartitions,\\n uint256 pnkPenalties,\\n address[] memory drawnJurors,\\n uint256 sumFeeRewardPaid,\\n uint256 sumPnkRewardPaid,\\n IERC20 feeToken\\n )\\n {\\n Round storage round = disputes[_disputeID].rounds[_round];\\n return (\\n round.disputeKitID,\\n round.pnkAtStakePerJuror,\\n round.totalFeesForJurors,\\n round.nbVotes,\\n round.repartitions,\\n round.pnkPenalties,\\n round.drawnJurors,\\n round.sumFeeRewardPaid,\\n round.sumPnkRewardPaid,\\n round.feeToken\\n );\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 staked, uint256 locked, uint256 nbCourts) {\\n Juror storage juror = jurors[_juror];\\n staked = juror.stakedPnk[_courtID];\\n locked = juror.lockedPnk[_courtID];\\n nbCourts = juror.courtIDs.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 non-primitive properties of a specified dispute kit node.\\n /// @param _disputeKitID The ID of the dispute kit.\\n /// @return children Indexes of children of this DK.\\n function getDisputeKitChildren(uint256 _disputeKitID) external view returns (uint256[] memory) {\\n return disputeKitNodes[_disputeKitID].children;\\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 Court storage court = courts[_courtID];\\n timesPerPeriod = court.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 getDisputeKitNodesLength() external view returns (uint256) {\\n return disputeKitNodes.length;\\n }\\n\\n /// @dev Gets the dispute kit for a specific `_disputeKitID`.\\n /// @param _disputeKitID The ID of the dispute kit.\\n function getDisputeKit(uint256 _disputeKitID) external view returns (IDisputeKit) {\\n return disputeKitNodes[_disputeKitID].disputeKit;\\n }\\n\\n /// @dev Gets the court identifiers where a specific `_juror` has staked.\\n /// @param _juror The address of the juror.\\n function getJurorCourtIDs(address _juror) public view returns (uint96[] memory) {\\n return jurors[_juror].courtIDs;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n CurrencyRate storage rate = currencyRates[_toToken];\\n return (_amountInEth * 10 ** rate.rateDecimals) / rate.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.\\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 Sets the specified juror's stake in a court.\\n /// `O(n + p * log_k(j))` where\\n /// `n` is the number of courts the juror has staked in,\\n /// `p` is the depth of the court tree,\\n /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,\\n /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.\\n /// @param _account The address of the juror.\\n /// @param _courtID The ID of the court.\\n /// @param _stake The new stake.\\n /// @param _penalty Penalized amount won't be transferred back to juror when the stake is lowered.\\n /// @return succeeded True if the call succeeded, false otherwise.\\n function _setStakeForAccount(\\n address _account,\\n uint96 _courtID,\\n uint256 _stake,\\n uint256 _penalty\\n ) internal returns (bool succeeded) {\\n if (_courtID == FORKING_COURT || _courtID > courts.length) return false;\\n\\n Juror storage juror = jurors[_account];\\n uint256 currentStake = juror.stakedPnk[_courtID];\\n\\n if (_stake != 0) {\\n // Check against locked PNKs in case the min stake was lowered.\\n if (_stake < courts[_courtID].minStake || _stake < juror.lockedPnk[_courtID]) return false;\\n }\\n\\n ISortitionModule.preStakeHookResult result = sortitionModule.preStakeHook(_account, _courtID, _stake, _penalty);\\n if (result == ISortitionModule.preStakeHookResult.failed) {\\n return false;\\n } else if (result == ISortitionModule.preStakeHookResult.delayed) {\\n emit StakeDelayed(_account, _courtID, _stake, _penalty);\\n return true;\\n }\\n\\n uint256 transferredAmount;\\n if (_stake >= currentStake) {\\n transferredAmount = _stake - currentStake;\\n if (transferredAmount > 0) {\\n if (pinakion.safeTransferFrom(_account, address(this), transferredAmount)) {\\n if (currentStake == 0) {\\n juror.courtIDs.push(_courtID);\\n }\\n } else {\\n return false;\\n }\\n }\\n } else {\\n if (_stake == 0) {\\n // Keep locked PNKs in the contract and release them after dispute is executed.\\n transferredAmount = currentStake - juror.lockedPnk[_courtID] - _penalty;\\n if (transferredAmount > 0) {\\n if (pinakion.safeTransfer(_account, transferredAmount)) {\\n for (uint256 i = juror.courtIDs.length; i > 0; i--) {\\n if (juror.courtIDs[i - 1] == _courtID) {\\n juror.courtIDs[i - 1] = juror.courtIDs[juror.courtIDs.length - 1];\\n juror.courtIDs.pop();\\n break;\\n }\\n }\\n } else {\\n return false;\\n }\\n }\\n } else {\\n transferredAmount = currentStake - _stake - _penalty;\\n if (transferredAmount > 0) {\\n if (!pinakion.safeTransfer(_account, transferredAmount)) {\\n return false;\\n }\\n }\\n }\\n }\\n\\n // Update juror's records.\\n juror.stakedPnk[_courtID] = _stake;\\n\\n sortitionModule.setStake(_account, _courtID, _stake);\\n emit StakeSet(_account, _courtID, _stake);\\n return true;\\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 >= disputeKitNodes.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 UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error DepthLevelMax();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableRootDKInGeneral();\\n error ArraysLengthMismatch();\\n error StakingFailed();\\n error WrongCaller();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\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 DisputeKitOnly();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n}\\n\",\"keccak256\":\"0xbbe5c690d5e8c80fb1802d46a2495c6cf3737cf912a0999377c1191df4aaa4fe\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/BaseDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\n\\nimport \\\"../interfaces/IDisputeKit.sol\\\";\\nimport \\\"../KlerosCore.sol\\\";\\n\\n/// @title BaseDisputeKit\\n/// Provides common basic behaviours to the Dispute Kit implementations.\\nabstract contract BaseDisputeKit is IDisputeKit {\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n\\n // ************************************* //\\n // * Function 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 /// @dev Constructor.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n constructor(address _governor, KlerosCore _core) {\\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 Checks that the chosen address satisfies certain conditions for being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return Whether the address can be drawn or not.\\n function _postDrawCheck(uint256 _coreDisputeID, address _juror) internal virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xa33f365553132a9cc4f0b5fdfe9e5be2337d13dfca71a65835450de17496b93f\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\n\\nimport \\\"./BaseDisputeKit.sol\\\";\\nimport \\\"../interfaces/IEvidence.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 BaseDisputeKit, IEvidence {\\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 => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address => mapping(uint256 => 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 }\\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 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\\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 notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n /** @dev Constructor.\\n * @param _governor The governor's address.\\n * @param _core The KlerosCore arbitrator.\\n */\\n constructor(address _governor, KlerosCore _core) BaseDisputeKit(_governor, _core) {}\\n\\n // ************************ //\\n // * Governance * //\\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 /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID\\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 // TODO: Handle the situation when no one has staked yet.\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, round.votes.length);\\n\\n if (_postDrawCheck(_coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\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 == KlerosCore.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 == KlerosCore.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 ||\\n round.votes[_voteIDs[i]].commit == keccak256(abi.encodePacked(_choice, _justification, _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 /// @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\\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 /// @dev Submits evidence for a dispute.\\n /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right evidence group ID.\\n /// @param _evidence IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'.\\n function submitEvidence(uint256 _externalDisputeID, string calldata _evidence) external {\\n emit Evidence(_externalDisputeID, msg.sender, _evidence);\\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 == KlerosCore.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 ) 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 /// @inheritdoc BaseDisputeKit\\n function _postDrawCheck(uint256 /*_coreDisputeID*/, address /*_juror*/) internal pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x9dcb03194794fc07721962bccfa95fbc27926a342d2c33c4e4eab32b3e1d9d48\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.18;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// 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 _arbitrableDisputeID The identifier of the dispute in the Arbitrable 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 _arbitrableDisputeID,\\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\":\"0x389326b1f749454ed179bdac2f9d6ce24a1ef944bbce976ca78b93f4e173354a\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.18;\\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\":\"0x453943ba5ccc94b9b9cdfd4afd3678682d62d8b90fe16b43e90215387d2f6a51\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n/// @custom:deployments: []\\n\\npragma solidity 0.8.18;\\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 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 /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID) 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 /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\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\":\"0x322c20f62706a690bc03f188531b77fe8eac85a9474f17fe15c2db494904c932\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IEvidence.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.18;\\n\\n/// @title IEvidence\\ninterface IEvidence {\\n /// @dev To be raised when evidence is submitted. Should point to the resource (evidences are not to be stored on chain due to gas considerations).\\n /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsability to submit the right external dispute ID.\\n /// @param _party The address of the party submiting the evidence. Note that 0x0 refers to evidence not submitted by any party.\\n /// @param _evidence IPFS path to evidence, example: '/ipfs/Qmarwkf7C9RuzDEJNnarT3WZ7kem5bk8DZAzx78acJjMFH/evidence.json'\\n event Evidence(uint256 indexed _externalDisputeID, address indexed _party, string _evidence);\\n}\\n\",\"keccak256\":\"0x3350da62267a5dad4616dafd9916fe3bfa4cdabfce124709ac3b7d087361e8c4\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\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 enum preStakeHookResult {\\n ok,\\n delayed,\\n failed\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(address _account, uint96 _courtID, uint256 _value) external;\\n\\n function setJurorInactive(address _account) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _voteID) external view returns (address);\\n\\n function preStakeHook(\\n address _account,\\n uint96 _courtID,\\n uint256 _stake,\\n uint256 _penalty\\n ) external returns (preStakeHookResult);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x28911aa78669746f40c4c3bce723db21600a49a74142c0fe378680b1b356d633\",\"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.18;\\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\":\"0x37a19df56a98cd466fb6e70b8c56e13bfc439221bfabd8c5108d36d0e3ffc0e5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604051620036b2380380620036b283398101604081905262000034916200007f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055620000be565b6001600160a01b03811681146200007c57600080fd5b50565b600080604083850312156200009357600080fd5b8251620000a08162000066565b6020840151909250620000b38162000066565b809150509250929050565b6135e480620000ce6000396000f3fe60806040526004361061016c5760003560e01c8063751accd0116100cc578063b6ede5401161007a578063b6ede540146104ac578063ba66fde7146104cc578063be467604146104ec578063da3beb8c14610502578063e349ad30146103d4578063e4c0aaf414610522578063f2f4eb261461054257600080fd5b8063751accd0146103b4578063796490f9146103d45780637c04034e146103ea5780638e4264601461040a578063a6a7f0eb1461042a578063a7cc08fe1461044a578063b34bfaa81461049657600080fd5b80634b2f0ea0116101295780634b2f0ea0146102965780634fe264fb146102ab578063564a565d146102cb5780635c92e2f6146102fa57806365540b961461031a57806369f3f041146103475780636d4cd8ea1461039457600080fd5b80630baa64d1146101715780630c340a24146101a65780631200aabc146101de5780631c3db16d14610219578063362c3479146102565780633b30414714610276575b600080fd5b34801561017d57600080fd5b5061019161018c366004612a98565b610562565b60405190151581526020015b60405180910390f35b3480156101b257600080fd5b506000546101c6906001600160a01b031681565b6040516001600160a01b03909116815260200161019d565b3480156101ea57600080fd5b5061020b6101f9366004612a98565b60036020526000908152604090205481565b60405190815260200161019d565b34801561022557600080fd5b50610239610234366004612a98565b6105d9565b60408051938452911515602084015215159082015260600161019d565b34801561026257600080fd5b5061020b610271366004612ac9565b610747565b34801561028257600080fd5b506101c6610291366004612a98565b610b1d565b6102a96102a4366004612b06565b610e10565b005b3480156102b757600080fd5b5061020b6102c6366004612b28565b611677565b3480156102d757600080fd5b506102eb6102e6366004612a98565b6117ba565b60405161019d93929190612ba4565b34801561030657600080fd5b506102a9610315366004612c19565b611880565b34801561032657600080fd5b5061033a610335366004612a98565b611b8d565b60405161019d9190612c6b565b34801561035357600080fd5b50610367610362366004612b28565b611c51565b604080519687529415156020870152938501929092526060840152608083015260a082015260c00161019d565b3480156103a057600080fd5b506101916103af366004612a98565b611d09565b3480156103c057600080fd5b506102a96103cf366004612d3a565b611d80565b3480156103e057600080fd5b5061020b61271081565b3480156103f657600080fd5b506102a9610405366004612da6565b611e52565b34801561041657600080fd5b506102a9610425366004612e3e565b61252e565b34801561043657600080fd5b506102a9610445366004612e9c565b61257a565b34801561045657600080fd5b5061046a610465366004612b28565b6125c3565b604080516001600160a01b0390951685526020850193909352918301521515606082015260800161019d565b3480156104a257600080fd5b5061020b614e2081565b3480156104b857600080fd5b506102a96104c7366004612ee7565b612689565b3480156104d857600080fd5b506101916104e7366004612b28565b61285e565b3480156104f857600080fd5b5061020b61138881565b34801561050e57600080fd5b5061020b61051d366004612b06565b6128f9565b34801561052e57600080fd5b506102a961053d366004612e3e565b612a4c565b34801561054e57600080fd5b506001546101c6906001600160a01b031681565b60008181526003602052604081205460028054839290811061058657610586612f41565b600091825260208220600590910201805490925082906105a890600190612f6d565b815481106105b8576105b8612f41565b60009182526020909120600c90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061060557610605612f41565b6000918252602082206005909102018054909250829061062790600190612f6d565b8154811061063757610637612f41565b60009182526020909120600c90910201600381015460ff169450905083610662578060010154610665565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156106b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d89190612fac565b50909350600492506106e8915050565b8160048111156106fa576106fa613013565b0361073d57600061070a88611b8d565b9050805160010361073b578060008151811061072857610728612f41565b6020026020010151965060009550600194505b505b5050509193909250565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190612fac565b509350505050806108115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b60008681526003602052604081205460028054909190811061083557610835612f41565b6000918252602080832088845260036005909302019182019052604082205481549193508391811061086957610869612f41565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600c9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa1580156108c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e89190613029565b5050600087815260078401602052604090205490915060ff16610932576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610a77565b8086036109a75760008681526006830160205260409020546109555760006109a0565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b86529093529220546109969190613065565b6109a0919061307c565b9450610a77565b600081815260078301602052604090205460ff16610a775781600601600083600a016001815481106109db576109db612f41565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610a1157610a11612f41565b9060005260206000200154815260200190815260200160002054610a35919061309e565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610a6a9190613065565b610a74919061307c565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610b11576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b6001546000906001600160a01b03163314610b4a5760405162461bcd60e51b8152600401610808906130b1565b600082815260036020526040902054600280548492908110610b6e57610b6e612f41565b600091825260209091206002600590920201015460ff1615610ba25760405162461bcd60e51b8152600401610808906130f5565b600083815260036020526040812054600280549091908110610bc657610bc6612f41565b60009182526020822060059091020180549092508290610be890600190612f6d565b81548110610bf857610bf8612f41565b90600052602060002090600c020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c81919061312c565b60015460405163564a565d60e01b8152600481018990529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf49190612fac565b50508554604051632638506b60e11b81526001600160601b03851660048201819052602482018d90526044820192909252939450926001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d80919061312c565b9650604080516080810182526001600160a01b03898116825260006020808401828152948401828152606085018381528a5460018082018d558c8652939094209551600490940290950180546001600160a01b0319169390941692909217835593519382019390935591516002830155516003909101805460ff1916911515919091179055505050505050919050565b600082815260036020526040902054600280548492908110610e3457610e34612f41565b600091825260209091206002600590920201015460ff1615610e685760405162461bcd60e51b8152600401610808906130f5565b600083815260036020526040812054600280549091908110610e8c57610e8c612f41565b906000526020600020906005020190508060010154831115610ef05760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610808565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610f3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f619190613149565b91509150814210158015610f7457508042105b610fb95760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610808565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015610ffa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101e9190613029565b505090508681036110335761271091506110b4565b6127106113886110438686612f6d565b61104d9190613065565b611057919061307c565b6110618542612f6d565b106110ae5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610808565b614e2091505b845460009086906110c790600190612f6d565b815481106110d7576110d7612f41565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600c949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015611136573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115a919061316d565b6111649190612f6d565b60008a815260078401602052604090205490915060ff16156111c85760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610808565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa158015611212573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611236919061316d565b905060006127106112478784613065565b611251919061307c565b61125b908361309e565b60008c81526006860160205260408120549192509082111561130c5760008c815260068601602052604090205434906112949084612f6d565b116112b95760008c81526006860160205260409020546112b49083612f6d565b6112bb565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f85604051611303929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f84529091528120805483929061133890849061309e565b909155505060008c81526006860160205260408120805483929061135d90849061309e565b909155505060008c8152600686016020526040902054821161142f5760008c81526006860160205260408120546009870180549192909161139f90849061309e565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a8501546001101561163a5782856009015461144c9190612f6d565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561149a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114be9190613186565b156114d75760028a01805460ff191660011790556115ba565b895460038b0160006114ea87600161309e565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600c02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161156591815260200190565b602060405180830381865afa158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a6919061316d565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b8152600401611607939291906131db565b6000604051808303818588803b15801561162057600080fd5b505af1158015611634573d6000803e3d6000fd5b50505050505b8034111561166857336108fc6116508334612f6d565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b60008381526003602052604081205460028054839290811061169b5761169b612f41565b600091825260208083208784526003600590930201918201905260408220548154919350839181106116cf576116cf612f41565b90600052602060002090600c020160000184815481106116f1576116f1612f41565b600091825260208220600154604051631c3db16d60e01b815260048082018c905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561174f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117739190613029565b506003850154919350915060ff168015611797575081836002015414806117975750805b156117aa576127109450505050506117b3565b60009450505050505b9392505050565b600281815481106117ca57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916117fd906131a1565b80601f0160208091040260200160405190810160405280929190818152602001828054611829906131a1565b80156118765780601f1061184b57610100808354040283529160200191611876565b820191906000526020600020905b81548152906001019060200180831161185957829003601f168201915b5050505050905083565b6000848152600360205260409020546002805486929081106118a4576118a4612f41565b600091825260209091206002600590920201015460ff16156118d85760405162461bcd60e51b8152600401610808906130f5565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611922573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119469190612fac565b5090935060019250611956915050565b81600481111561196857611968613013565b146119c55760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610808565b82611a025760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610808565b600086815260036020526040812054600280549091908110611a2657611a26612f41565b60009182526020822060059091020180549092508290611a4890600190612f6d565b81548110611a5857611a58612f41565b90600052602060002090600c0201905060005b86811015611b26573382898984818110611a8757611a87612f41565b9050602002013581548110611a9e57611a9e612f41565b60009182526020909120600490910201546001600160a01b031614611ad55760405162461bcd60e51b815260040161080890613275565b8582898984818110611ae957611ae9612f41565b9050602002013581548110611b0057611b00612f41565b600091825260209091206001600490920201015580611b1e816132ac565b915050611a6b565b5086869050816005016000828254611b3e919061309e565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611b7b908b908b908b906132f7565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611bb357611bb3612f41565b60009182526020822060059091020180549092508290611bd590600190612f6d565b81548110611be557611be5612f41565b90600052602060002090600c0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c4357602002820191906000526020600020905b815481526020019060010190808311611c2f575b505050505092505050919050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611c8257611c82612f41565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611cb657611cb6612f41565b600091825260208083206001600c909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611d2d57611d2d612f41565b60009182526020822060059091020180549092508290611d4f90600190612f6d565b81548110611d5f57611d5f612f41565b60009182526020909120600c90910201805460049091015414949350505050565b6000546001600160a01b03163314611daa5760405162461bcd60e51b81526004016108089061331b565b6000836001600160a01b03168383604051611dc5919061335d565b60006040518083038185875af1925050503d8060008114611e02576040519150601f19603f3d011682016040523d82523d6000602084013e611e07565b606091505b5050905080611e4c5760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610808565b50505050565b600086815260036020526040902054600280548892908110611e7657611e76612f41565b600091825260209091206002600590920201015460ff1615611eaa5760405162461bcd60e51b8152600401610808906130f5565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611ef4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f189190612fac565b5090935060029250611f28915050565b816004811115611f3a57611f3a613013565b14611f955760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610808565b85611fd75760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610808565b600088815260036020526040812054600280549091908110611ffb57611ffb612f41565b9060005260206000209060050201905080600101548611156120565760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610808565b8054600090829061206990600190612f6d565b8154811061207957612079612f41565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600c9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612fac565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121779190613379565b505050505091505060005b8a8110156123f45733848d8d8481811061219e5761219e612f41565b90506020020135815481106121b5576121b5612f41565b60009182526020909120600490910201546001600160a01b0316146121ec5760405162461bcd60e51b815260040161080890613275565b811580612260575089888a604051602001612209939291906133e3565b60405160208183030381529060405280519060200120846000018d8d8481811061223557612235612f41565b905060200201358154811061224c5761224c612f41565b906000526020600020906004020160010154145b6122d25760405162461bcd60e51b815260206004820152603d60248201527f54686520636f6d6d6974206d757374206d61746368207468652063686f69636560448201527f20696e20636f7572747320776974682068696464656e20766f7465732e0000006064820152608401610808565b838c8c838181106122e5576122e5612f41565b90506020020135815481106122fc576122fc612f41565b600091825260209091206003600490920201015460ff16156123555760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610808565b89848d8d8481811061236957612369612f41565b905060200201358154811061238057612380612f41565b60009182526020909120600260049092020101556001848d8d848181106123a9576123a9612f41565b90506020020135815481106123c0576123c0612f41565b60009182526020909120600490910201600301805460ff1916911515919091179055806123ec816132ac565b915050612182565b508a8a905083600401600082825461240c919061309e565b90915550506000898152600284016020526040812080548c929061243190849061309e565b90915550506001830154890361246057600383015460ff161561245b5760038301805460ff191690555b6124d9565b60018301546000908152600284016020526040808220548b8352912054036124a257600383015460ff1661245b5760038301805460ff191660011790556124d9565b60018301546000908152600284016020526040808220548b835291205411156124d9576001830189905560038301805460ff191690555b88336001600160a01b03168d7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48e8e8c60405161251893929190613410565b60405180910390a4505050505050505050505050565b6000546001600160a01b031633146125585760405162461bcd60e51b81526004016108089061331b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b0316837f39935cf45244bc296a03d6aef1cf17779033ee27090ce9c68d432367ce10699684846040516125b6929190613469565b60405180910390a3505050565b60008060008060006002600360008a815260200190815260200160002054815481106125f1576125f1612f41565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061262557612625612f41565b90600052602060002090600c0201600001878154811061264757612647612f41565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146126b35760405162461bcd60e51b8152600401610808906130b1565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad20161273e8587836134d4565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127b9919061316d565b6127c39190612f6d565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600c909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab581089061284c908a908a908a90613594565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061288257612882612f41565b600091825260208083208784526003600590930201918201905260408220548154919350839181106128b6576128b6612f41565b90600052602060002090600c020160000184815481106128d8576128d8612f41565b600091825260209091206004909102016003015460ff169695505050505050565b60008281526003602052604081205460028054839290811061291d5761291d612f41565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061295157612951612f41565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600c93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156129b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d49190613029565b5091509150826004015460001480612a03575080158015612a0357506000828152600284016020526040902054155b15612a15576000945050505050612a46565b8015612a2a575050600401549150612a469050565b506000908152600290910160205260409020549150612a469050565b92915050565b6000546001600160a01b03163314612a765760405162461bcd60e51b81526004016108089061331b565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215612aaa57600080fd5b5035919050565b6001600160a01b0381168114612ac657600080fd5b50565b60008060008060808587031215612adf57600080fd5b843593506020850135612af181612ab1565b93969395505050506040820135916060013590565b60008060408385031215612b1957600080fd5b50508035926020909101359150565b600080600060608486031215612b3d57600080fd5b505081359360208301359350604090920135919050565b60005b83811015612b6f578181015183820152602001612b57565b50506000910152565b60008151808452612b90816020860160208601612b54565b601f01601f19169290920160200192915050565b8381528215156020820152606060408201526000612bc56060830184612b78565b95945050505050565b60008083601f840112612be057600080fd5b5081356001600160401b03811115612bf757600080fd5b6020830191508360208260051b8501011115612c1257600080fd5b9250929050565b60008060008060608587031215612c2f57600080fd5b8435935060208501356001600160401b03811115612c4c57600080fd5b612c5887828801612bce565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015612ca357835183529284019291840191600101612c87565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115612cdf57612cdf612caf565b604051601f8501601f19908116603f01168101908282118183101715612d0757612d07612caf565b81604052809350858152868686011115612d2057600080fd5b858560208301376000602087830101525050509392505050565b600080600060608486031215612d4f57600080fd5b8335612d5a81612ab1565b92506020840135915060408401356001600160401b03811115612d7c57600080fd5b8401601f81018613612d8d57600080fd5b612d9c86823560208401612cc5565b9150509250925092565b60008060008060008060a08789031215612dbf57600080fd5b8635955060208701356001600160401b0380821115612ddd57600080fd5b612de98a838b01612bce565b909750955060408901359450606089013593506080890135915080821115612e1057600080fd5b508701601f81018913612e2257600080fd5b612e3189823560208401612cc5565b9150509295509295509295565b600060208284031215612e5057600080fd5b81356117b381612ab1565b60008083601f840112612e6d57600080fd5b5081356001600160401b03811115612e8457600080fd5b602083019150836020828501011115612c1257600080fd5b600080600060408486031215612eb157600080fd5b8335925060208401356001600160401b03811115612ece57600080fd5b612eda86828701612e5b565b9497909650939450505050565b600080600080600060808688031215612eff57600080fd5b853594506020860135935060408601356001600160401b03811115612f2357600080fd5b612f2f88828901612e5b565b96999598509660600135949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612a4657612a46612f57565b80516001600160601b0381168114612f9757600080fd5b919050565b80518015158114612f9757600080fd5b600080600080600060a08688031215612fc457600080fd5b612fcd86612f80565b94506020860151612fdd81612ab1565b604087015190945060058110612ff257600080fd5b925061300060608701612f9c565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b60008060006060848603121561303e57600080fd5b8351925061304e60208501612f9c565b915061305c60408501612f9c565b90509250925092565b8082028115828204841417612a4657612a46612f57565b60008261309957634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115612a4657612a46612f57565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b60006020828403121561313e57600080fd5b81516117b381612ab1565b6000806040838503121561315c57600080fd5b505080516020909101519092909150565b60006020828403121561317f57600080fd5b5051919050565b60006020828403121561319857600080fd5b6117b382612f9c565b600181811c908216806131b557607f821691505b6020821081036131d557634e487b7160e01b600052602260045260246000fd5b50919050565b83815260006020848184015260606040840152600084546131fb816131a1565b806060870152608060018084166000811461321d576001811461323757613265565b60ff1985168984015283151560051b890183019550613265565b896000528660002060005b8581101561325d5781548b8201860152908301908801613242565b8a0184019650505b50939a9950505050505050505050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6000600182016132be576132be612f57565b5060010190565b81835260006001600160fb1b038311156132de57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061330b6040830185876132c5565b9050826020830152949350505050565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b6000825161336f818460208701612b54565b9190910192915050565b600080600080600080600060e0888a03121561339457600080fd5b61339d88612f80565b96506133ab60208901612f9c565b955060408801519450606088015193506080880151925060a088015191506133d560c08901612f9c565b905092959891949750929550565b838152600083516133fb816020850160208801612b54565b60209201918201929092526040019392505050565b6040815260006134246040830185876132c5565b82810360208401526134368185612b78565b9695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208152600061347d602083018486613440565b949350505050565b601f8211156134cf57600081815260208120601f850160051c810160208610156134ac5750805b601f850160051c820191505b818110156134cb578281556001016134b8565b5050505b505050565b6001600160401b038311156134eb576134eb612caf565b6134ff836134f983546131a1565b83613485565b6000601f841160018114613533576000851561351b5750838201355b600019600387901b1c1916600186901b17835561358d565b600083815260209020601f19861690835b828110156135645786850135825560209485019460019092019101613544565b50868210156135815760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b838152604060208201526000612bc560408301848661344056fea2646970667358221220628de1ab169f57640137ced98d7412a09254218bc63ad4d362d8482d9c62deff64736f6c63430008120033", + "deployedBytecode": "0x60806040526004361061016c5760003560e01c8063751accd0116100cc578063b6ede5401161007a578063b6ede540146104ac578063ba66fde7146104cc578063be467604146104ec578063da3beb8c14610502578063e349ad30146103d4578063e4c0aaf414610522578063f2f4eb261461054257600080fd5b8063751accd0146103b4578063796490f9146103d45780637c04034e146103ea5780638e4264601461040a578063a6a7f0eb1461042a578063a7cc08fe1461044a578063b34bfaa81461049657600080fd5b80634b2f0ea0116101295780634b2f0ea0146102965780634fe264fb146102ab578063564a565d146102cb5780635c92e2f6146102fa57806365540b961461031a57806369f3f041146103475780636d4cd8ea1461039457600080fd5b80630baa64d1146101715780630c340a24146101a65780631200aabc146101de5780631c3db16d14610219578063362c3479146102565780633b30414714610276575b600080fd5b34801561017d57600080fd5b5061019161018c366004612a98565b610562565b60405190151581526020015b60405180910390f35b3480156101b257600080fd5b506000546101c6906001600160a01b031681565b6040516001600160a01b03909116815260200161019d565b3480156101ea57600080fd5b5061020b6101f9366004612a98565b60036020526000908152604090205481565b60405190815260200161019d565b34801561022557600080fd5b50610239610234366004612a98565b6105d9565b60408051938452911515602084015215159082015260600161019d565b34801561026257600080fd5b5061020b610271366004612ac9565b610747565b34801561028257600080fd5b506101c6610291366004612a98565b610b1d565b6102a96102a4366004612b06565b610e10565b005b3480156102b757600080fd5b5061020b6102c6366004612b28565b611677565b3480156102d757600080fd5b506102eb6102e6366004612a98565b6117ba565b60405161019d93929190612ba4565b34801561030657600080fd5b506102a9610315366004612c19565b611880565b34801561032657600080fd5b5061033a610335366004612a98565b611b8d565b60405161019d9190612c6b565b34801561035357600080fd5b50610367610362366004612b28565b611c51565b604080519687529415156020870152938501929092526060840152608083015260a082015260c00161019d565b3480156103a057600080fd5b506101916103af366004612a98565b611d09565b3480156103c057600080fd5b506102a96103cf366004612d3a565b611d80565b3480156103e057600080fd5b5061020b61271081565b3480156103f657600080fd5b506102a9610405366004612da6565b611e52565b34801561041657600080fd5b506102a9610425366004612e3e565b61252e565b34801561043657600080fd5b506102a9610445366004612e9c565b61257a565b34801561045657600080fd5b5061046a610465366004612b28565b6125c3565b604080516001600160a01b0390951685526020850193909352918301521515606082015260800161019d565b3480156104a257600080fd5b5061020b614e2081565b3480156104b857600080fd5b506102a96104c7366004612ee7565b612689565b3480156104d857600080fd5b506101916104e7366004612b28565b61285e565b3480156104f857600080fd5b5061020b61138881565b34801561050e57600080fd5b5061020b61051d366004612b06565b6128f9565b34801561052e57600080fd5b506102a961053d366004612e3e565b612a4c565b34801561054e57600080fd5b506001546101c6906001600160a01b031681565b60008181526003602052604081205460028054839290811061058657610586612f41565b600091825260208220600590910201805490925082906105a890600190612f6d565b815481106105b8576105b8612f41565b60009182526020909120600c90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061060557610605612f41565b6000918252602082206005909102018054909250829061062790600190612f6d565b8154811061063757610637612f41565b60009182526020909120600c90910201600381015460ff169450905083610662578060010154610665565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156106b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d89190612fac565b50909350600492506106e8915050565b8160048111156106fa576106fa613013565b0361073d57600061070a88611b8d565b9050805160010361073b578060008151811061072857610728612f41565b6020026020010151965060009550600194505b505b5050509193909250565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190612fac565b509350505050806108115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b60008681526003602052604081205460028054909190811061083557610835612f41565b6000918252602080832088845260036005909302019182019052604082205481549193508391811061086957610869612f41565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600c9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa1580156108c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e89190613029565b5050600087815260078401602052604090205490915060ff16610932576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610a77565b8086036109a75760008681526006830160205260409020546109555760006109a0565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b86529093529220546109969190613065565b6109a0919061307c565b9450610a77565b600081815260078301602052604090205460ff16610a775781600601600083600a016001815481106109db576109db612f41565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610a1157610a11612f41565b9060005260206000200154815260200190815260200160002054610a35919061309e565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610a6a9190613065565b610a74919061307c565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610b11576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b6001546000906001600160a01b03163314610b4a5760405162461bcd60e51b8152600401610808906130b1565b600082815260036020526040902054600280548492908110610b6e57610b6e612f41565b600091825260209091206002600590920201015460ff1615610ba25760405162461bcd60e51b8152600401610808906130f5565b600083815260036020526040812054600280549091908110610bc657610bc6612f41565b60009182526020822060059091020180549092508290610be890600190612f6d565b81548110610bf857610bf8612f41565b90600052602060002090600c020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c81919061312c565b60015460405163564a565d60e01b8152600481018990529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf49190612fac565b50508554604051632638506b60e11b81526001600160601b03851660048201819052602482018d90526044820192909252939450926001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d80919061312c565b9650604080516080810182526001600160a01b03898116825260006020808401828152948401828152606085018381528a5460018082018d558c8652939094209551600490940290950180546001600160a01b0319169390941692909217835593519382019390935591516002830155516003909101805460ff1916911515919091179055505050505050919050565b600082815260036020526040902054600280548492908110610e3457610e34612f41565b600091825260209091206002600590920201015460ff1615610e685760405162461bcd60e51b8152600401610808906130f5565b600083815260036020526040812054600280549091908110610e8c57610e8c612f41565b906000526020600020906005020190508060010154831115610ef05760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610808565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610f3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f619190613149565b91509150814210158015610f7457508042105b610fb95760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610808565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015610ffa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101e9190613029565b505090508681036110335761271091506110b4565b6127106113886110438686612f6d565b61104d9190613065565b611057919061307c565b6110618542612f6d565b106110ae5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610808565b614e2091505b845460009086906110c790600190612f6d565b815481106110d7576110d7612f41565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600c949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015611136573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115a919061316d565b6111649190612f6d565b60008a815260078401602052604090205490915060ff16156111c85760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610808565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa158015611212573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611236919061316d565b905060006127106112478784613065565b611251919061307c565b61125b908361309e565b60008c81526006860160205260408120549192509082111561130c5760008c815260068601602052604090205434906112949084612f6d565b116112b95760008c81526006860160205260409020546112b49083612f6d565b6112bb565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f85604051611303929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f84529091528120805483929061133890849061309e565b909155505060008c81526006860160205260408120805483929061135d90849061309e565b909155505060008c8152600686016020526040902054821161142f5760008c81526006860160205260408120546009870180549192909161139f90849061309e565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a8501546001101561163a5782856009015461144c9190612f6d565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561149a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114be9190613186565b156114d75760028a01805460ff191660011790556115ba565b895460038b0160006114ea87600161309e565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600c02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161156591815260200190565b602060405180830381865afa158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a6919061316d565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b8152600401611607939291906131db565b6000604051808303818588803b15801561162057600080fd5b505af1158015611634573d6000803e3d6000fd5b50505050505b8034111561166857336108fc6116508334612f6d565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b60008381526003602052604081205460028054839290811061169b5761169b612f41565b600091825260208083208784526003600590930201918201905260408220548154919350839181106116cf576116cf612f41565b90600052602060002090600c020160000184815481106116f1576116f1612f41565b600091825260208220600154604051631c3db16d60e01b815260048082018c905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561174f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117739190613029565b506003850154919350915060ff168015611797575081836002015414806117975750805b156117aa576127109450505050506117b3565b60009450505050505b9392505050565b600281815481106117ca57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916117fd906131a1565b80601f0160208091040260200160405190810160405280929190818152602001828054611829906131a1565b80156118765780601f1061184b57610100808354040283529160200191611876565b820191906000526020600020905b81548152906001019060200180831161185957829003601f168201915b5050505050905083565b6000848152600360205260409020546002805486929081106118a4576118a4612f41565b600091825260209091206002600590920201015460ff16156118d85760405162461bcd60e51b8152600401610808906130f5565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611922573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119469190612fac565b5090935060019250611956915050565b81600481111561196857611968613013565b146119c55760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610808565b82611a025760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610808565b600086815260036020526040812054600280549091908110611a2657611a26612f41565b60009182526020822060059091020180549092508290611a4890600190612f6d565b81548110611a5857611a58612f41565b90600052602060002090600c0201905060005b86811015611b26573382898984818110611a8757611a87612f41565b9050602002013581548110611a9e57611a9e612f41565b60009182526020909120600490910201546001600160a01b031614611ad55760405162461bcd60e51b815260040161080890613275565b8582898984818110611ae957611ae9612f41565b9050602002013581548110611b0057611b00612f41565b600091825260209091206001600490920201015580611b1e816132ac565b915050611a6b565b5086869050816005016000828254611b3e919061309e565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611b7b908b908b908b906132f7565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611bb357611bb3612f41565b60009182526020822060059091020180549092508290611bd590600190612f6d565b81548110611be557611be5612f41565b90600052602060002090600c0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c4357602002820191906000526020600020905b815481526020019060010190808311611c2f575b505050505092505050919050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611c8257611c82612f41565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611cb657611cb6612f41565b600091825260208083206001600c909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611d2d57611d2d612f41565b60009182526020822060059091020180549092508290611d4f90600190612f6d565b81548110611d5f57611d5f612f41565b60009182526020909120600c90910201805460049091015414949350505050565b6000546001600160a01b03163314611daa5760405162461bcd60e51b81526004016108089061331b565b6000836001600160a01b03168383604051611dc5919061335d565b60006040518083038185875af1925050503d8060008114611e02576040519150601f19603f3d011682016040523d82523d6000602084013e611e07565b606091505b5050905080611e4c5760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610808565b50505050565b600086815260036020526040902054600280548892908110611e7657611e76612f41565b600091825260209091206002600590920201015460ff1615611eaa5760405162461bcd60e51b8152600401610808906130f5565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611ef4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f189190612fac565b5090935060029250611f28915050565b816004811115611f3a57611f3a613013565b14611f955760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610808565b85611fd75760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610808565b600088815260036020526040812054600280549091908110611ffb57611ffb612f41565b9060005260206000209060050201905080600101548611156120565760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610808565b8054600090829061206990600190612f6d565b8154811061207957612079612f41565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600c9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612fac565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121779190613379565b505050505091505060005b8a8110156123f45733848d8d8481811061219e5761219e612f41565b90506020020135815481106121b5576121b5612f41565b60009182526020909120600490910201546001600160a01b0316146121ec5760405162461bcd60e51b815260040161080890613275565b811580612260575089888a604051602001612209939291906133e3565b60405160208183030381529060405280519060200120846000018d8d8481811061223557612235612f41565b905060200201358154811061224c5761224c612f41565b906000526020600020906004020160010154145b6122d25760405162461bcd60e51b815260206004820152603d60248201527f54686520636f6d6d6974206d757374206d61746368207468652063686f69636560448201527f20696e20636f7572747320776974682068696464656e20766f7465732e0000006064820152608401610808565b838c8c838181106122e5576122e5612f41565b90506020020135815481106122fc576122fc612f41565b600091825260209091206003600490920201015460ff16156123555760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610808565b89848d8d8481811061236957612369612f41565b905060200201358154811061238057612380612f41565b60009182526020909120600260049092020101556001848d8d848181106123a9576123a9612f41565b90506020020135815481106123c0576123c0612f41565b60009182526020909120600490910201600301805460ff1916911515919091179055806123ec816132ac565b915050612182565b508a8a905083600401600082825461240c919061309e565b90915550506000898152600284016020526040812080548c929061243190849061309e565b90915550506001830154890361246057600383015460ff161561245b5760038301805460ff191690555b6124d9565b60018301546000908152600284016020526040808220548b8352912054036124a257600383015460ff1661245b5760038301805460ff191660011790556124d9565b60018301546000908152600284016020526040808220548b835291205411156124d9576001830189905560038301805460ff191690555b88336001600160a01b03168d7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48e8e8c60405161251893929190613410565b60405180910390a4505050505050505050505050565b6000546001600160a01b031633146125585760405162461bcd60e51b81526004016108089061331b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b0316837f39935cf45244bc296a03d6aef1cf17779033ee27090ce9c68d432367ce10699684846040516125b6929190613469565b60405180910390a3505050565b60008060008060006002600360008a815260200190815260200160002054815481106125f1576125f1612f41565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061262557612625612f41565b90600052602060002090600c0201600001878154811061264757612647612f41565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146126b35760405162461bcd60e51b8152600401610808906130b1565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad20161273e8587836134d4565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127b9919061316d565b6127c39190612f6d565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600c909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab581089061284c908a908a908a90613594565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061288257612882612f41565b600091825260208083208784526003600590930201918201905260408220548154919350839181106128b6576128b6612f41565b90600052602060002090600c020160000184815481106128d8576128d8612f41565b600091825260209091206004909102016003015460ff169695505050505050565b60008281526003602052604081205460028054839290811061291d5761291d612f41565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061295157612951612f41565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600c93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156129b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d49190613029565b5091509150826004015460001480612a03575080158015612a0357506000828152600284016020526040902054155b15612a15576000945050505050612a46565b8015612a2a575050600401549150612a469050565b506000908152600290910160205260409020549150612a469050565b92915050565b6000546001600160a01b03163314612a765760405162461bcd60e51b81526004016108089061331b565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215612aaa57600080fd5b5035919050565b6001600160a01b0381168114612ac657600080fd5b50565b60008060008060808587031215612adf57600080fd5b843593506020850135612af181612ab1565b93969395505050506040820135916060013590565b60008060408385031215612b1957600080fd5b50508035926020909101359150565b600080600060608486031215612b3d57600080fd5b505081359360208301359350604090920135919050565b60005b83811015612b6f578181015183820152602001612b57565b50506000910152565b60008151808452612b90816020860160208601612b54565b601f01601f19169290920160200192915050565b8381528215156020820152606060408201526000612bc56060830184612b78565b95945050505050565b60008083601f840112612be057600080fd5b5081356001600160401b03811115612bf757600080fd5b6020830191508360208260051b8501011115612c1257600080fd5b9250929050565b60008060008060608587031215612c2f57600080fd5b8435935060208501356001600160401b03811115612c4c57600080fd5b612c5887828801612bce565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015612ca357835183529284019291840191600101612c87565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b0380841115612cdf57612cdf612caf565b604051601f8501601f19908116603f01168101908282118183101715612d0757612d07612caf565b81604052809350858152868686011115612d2057600080fd5b858560208301376000602087830101525050509392505050565b600080600060608486031215612d4f57600080fd5b8335612d5a81612ab1565b92506020840135915060408401356001600160401b03811115612d7c57600080fd5b8401601f81018613612d8d57600080fd5b612d9c86823560208401612cc5565b9150509250925092565b60008060008060008060a08789031215612dbf57600080fd5b8635955060208701356001600160401b0380821115612ddd57600080fd5b612de98a838b01612bce565b909750955060408901359450606089013593506080890135915080821115612e1057600080fd5b508701601f81018913612e2257600080fd5b612e3189823560208401612cc5565b9150509295509295509295565b600060208284031215612e5057600080fd5b81356117b381612ab1565b60008083601f840112612e6d57600080fd5b5081356001600160401b03811115612e8457600080fd5b602083019150836020828501011115612c1257600080fd5b600080600060408486031215612eb157600080fd5b8335925060208401356001600160401b03811115612ece57600080fd5b612eda86828701612e5b565b9497909650939450505050565b600080600080600060808688031215612eff57600080fd5b853594506020860135935060408601356001600160401b03811115612f2357600080fd5b612f2f88828901612e5b565b96999598509660600135949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612a4657612a46612f57565b80516001600160601b0381168114612f9757600080fd5b919050565b80518015158114612f9757600080fd5b600080600080600060a08688031215612fc457600080fd5b612fcd86612f80565b94506020860151612fdd81612ab1565b604087015190945060058110612ff257600080fd5b925061300060608701612f9c565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b60008060006060848603121561303e57600080fd5b8351925061304e60208501612f9c565b915061305c60408501612f9c565b90509250925092565b8082028115828204841417612a4657612a46612f57565b60008261309957634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115612a4657612a46612f57565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b60006020828403121561313e57600080fd5b81516117b381612ab1565b6000806040838503121561315c57600080fd5b505080516020909101519092909150565b60006020828403121561317f57600080fd5b5051919050565b60006020828403121561319857600080fd5b6117b382612f9c565b600181811c908216806131b557607f821691505b6020821081036131d557634e487b7160e01b600052602260045260246000fd5b50919050565b83815260006020848184015260606040840152600084546131fb816131a1565b806060870152608060018084166000811461321d576001811461323757613265565b60ff1985168984015283151560051b890183019550613265565b896000528660002060005b8581101561325d5781548b8201860152908301908801613242565b8a0184019650505b50939a9950505050505050505050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6000600182016132be576132be612f57565b5060010190565b81835260006001600160fb1b038311156132de57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061330b6040830185876132c5565b9050826020830152949350505050565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b6000825161336f818460208701612b54565b9190910192915050565b600080600080600080600060e0888a03121561339457600080fd5b61339d88612f80565b96506133ab60208901612f9c565b955060408801519450606088015193506080880151925060a088015191506133d560c08901612f9c565b905092959891949750929550565b838152600083516133fb816020850160208801612b54565b60209201918201929092526040019392505050565b6040815260006134246040830185876132c5565b82810360208401526134368185612b78565b9695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208152600061347d602083018486613440565b949350505050565b601f8211156134cf57600081815260208120601f850160051c810160208610156134ac5750805b601f850160051c820191505b818110156134cb578281556001016134b8565b5050505b505050565b6001600160401b038311156134eb576134eb612caf565b6134ff836134f983546131a1565b83613485565b6000601f841160018114613533576000851561351b5750838201355b600019600387901b1c1916600186901b17835561358d565b600083815260209020601f19861690835b828110156135645786850135825560209485019460019092019101613544565b50868210156135815760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b838152604060208201526000612bc560408301848661344056fea2646970667358221220628de1ab169f57640137ced98d7412a09254218bc63ad4d362d8482d9c62deff64736f6c63430008120033", "devdoc": { "events": { "ChoiceFunded(uint256,uint256,uint256)": { @@ -1104,7 +1104,7 @@ "storageLayout": { "storage": [ { - "astId": 9998, + "astId": 4016, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "governor", "offset": 0, @@ -1112,23 +1112,23 @@ "type": "t_address" }, { - "astId": 10001, + "astId": 4019, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "core", "offset": 0, "slot": "1", - "type": "t_contract(KlerosCore)6640" + "type": "t_contract(KlerosCore)4007" }, { - "astId": 10171, + "astId": 4189, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "disputes", "offset": 0, "slot": "2", - "type": "t_array(t_struct(Dispute)10108_storage)dyn_storage" + "type": "t_array(t_struct(Dispute)4126_storage)dyn_storage" }, { - "astId": 10175, + "astId": 4193, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "coreDisputeIDToLocal", "offset": 0, @@ -1142,20 +1142,20 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_struct(Dispute)10108_storage)dyn_storage": { - "base": "t_struct(Dispute)10108_storage", + "t_array(t_struct(Dispute)4126_storage)dyn_storage": { + "base": "t_struct(Dispute)4126_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassic.Dispute[]", "numberOfBytes": "32" }, - "t_array(t_struct(Round)10146_storage)dyn_storage": { - "base": "t_struct(Round)10146_storage", + "t_array(t_struct(Round)4164_storage)dyn_storage": { + "base": "t_struct(Round)4164_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassic.Round[]", "numberOfBytes": "32" }, - "t_array(t_struct(Vote)10155_storage)dyn_storage": { - "base": "t_struct(Vote)10155_storage", + "t_array(t_struct(Vote)4173_storage)dyn_storage": { + "base": "t_struct(Vote)4173_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassic.Vote[]", "numberOfBytes": "32" @@ -1181,7 +1181,7 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_contract(KlerosCore)6640": { + "t_contract(KlerosCore)4007": { "encoding": "inplace", "label": "contract KlerosCore", "numberOfBytes": "20" @@ -1207,20 +1207,20 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Dispute)10108_storage": { + "t_struct(Dispute)4126_storage": { "encoding": "inplace", "label": "struct DisputeKitClassic.Dispute", "members": [ { - "astId": 10097, + "astId": 4115, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "rounds", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Round)10146_storage)dyn_storage" + "type": "t_array(t_struct(Round)4164_storage)dyn_storage" }, { - "astId": 10099, + "astId": 4117, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "numberOfChoices", "offset": 0, @@ -1228,7 +1228,7 @@ "type": "t_uint256" }, { - "astId": 10101, + "astId": 4119, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "jumped", "offset": 0, @@ -1236,7 +1236,7 @@ "type": "t_bool" }, { - "astId": 10105, + "astId": 4123, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "coreRoundIDToLocal", "offset": 0, @@ -1244,7 +1244,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 10107, + "astId": 4125, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "extraData", "offset": 0, @@ -1254,20 +1254,20 @@ ], "numberOfBytes": "160" }, - "t_struct(Round)10146_storage": { + "t_struct(Round)4164_storage": { "encoding": "inplace", "label": "struct DisputeKitClassic.Round", "members": [ { - "astId": 10112, + "astId": 4130, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "votes", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Vote)10155_storage)dyn_storage" + "type": "t_array(t_struct(Vote)4173_storage)dyn_storage" }, { - "astId": 10114, + "astId": 4132, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "winningChoice", "offset": 0, @@ -1275,7 +1275,7 @@ "type": "t_uint256" }, { - "astId": 10118, + "astId": 4136, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "counts", "offset": 0, @@ -1283,7 +1283,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 10120, + "astId": 4138, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "tied", "offset": 0, @@ -1291,7 +1291,7 @@ "type": "t_bool" }, { - "astId": 10122, + "astId": 4140, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "totalVoted", "offset": 0, @@ -1299,7 +1299,7 @@ "type": "t_uint256" }, { - "astId": 10124, + "astId": 4142, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "totalCommitted", "offset": 0, @@ -1307,7 +1307,7 @@ "type": "t_uint256" }, { - "astId": 10128, + "astId": 4146, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "paidFees", "offset": 0, @@ -1315,7 +1315,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 10132, + "astId": 4150, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "hasPaid", "offset": 0, @@ -1323,7 +1323,7 @@ "type": "t_mapping(t_uint256,t_bool)" }, { - "astId": 10138, + "astId": 4156, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "contributions", "offset": 0, @@ -1331,7 +1331,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 10140, + "astId": 4158, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "feeRewards", "offset": 0, @@ -1339,7 +1339,7 @@ "type": "t_uint256" }, { - "astId": 10143, + "astId": 4161, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "fundedChoices", "offset": 0, @@ -1347,7 +1347,7 @@ "type": "t_array(t_uint256)dyn_storage" }, { - "astId": 10145, + "astId": 4163, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "nbVotes", "offset": 0, @@ -1357,12 +1357,12 @@ ], "numberOfBytes": "384" }, - "t_struct(Vote)10155_storage": { + "t_struct(Vote)4173_storage": { "encoding": "inplace", "label": "struct DisputeKitClassic.Vote", "members": [ { - "astId": 10148, + "astId": 4166, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "account", "offset": 0, @@ -1370,7 +1370,7 @@ "type": "t_address" }, { - "astId": 10150, + "astId": 4168, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "commit", "offset": 0, @@ -1378,7 +1378,7 @@ "type": "t_bytes32" }, { - "astId": 10152, + "astId": 4170, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "choice", "offset": 0, @@ -1386,7 +1386,7 @@ "type": "t_uint256" }, { - "astId": 10154, + "astId": 4172, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "voted", "offset": 0, diff --git a/contracts/src/arbitration/SortitionModule.sol b/contracts/src/arbitration/SortitionModule.sol index ac9eef13a..f870ed52a 100644 --- a/contracts/src/arbitration/SortitionModule.sol +++ b/contracts/src/arbitration/SortitionModule.sol @@ -289,11 +289,15 @@ contract SortitionModule is ISortitionModule { require(phase == Phase.drawing, "Wrong phase."); SortitionSumTree storage tree = sortitionSumTrees[_key]; - uint256 treeIndex = 0; + if (tree.nodes[0] == 0) { + return address(0); // No jurors staked. + } + uint256 currentDrawnNumber = uint256(keccak256(abi.encodePacked(randomNumber, _coreDisputeID, _voteID))) % tree.nodes[0]; // While it still has children + uint256 treeIndex = 0; while ((tree.K * treeIndex) + 1 < tree.nodes.length) { for (uint256 i = 1; i <= tree.K; i++) { // Loop over children. diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol index 0467bf0ba..4eb8fb523 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol @@ -557,18 +557,8 @@ contract DisputeKitClassic is BaseDisputeKit, IEvidence { // * Internal * // // ************************************* // - /// @dev Checks that the chosen address satisfies certain conditions for being drawn. - /// @param _coreDisputeID ID of the dispute in the core contract. - /// @param _juror Chosen address. - /// @return Whether the address can be drawn or not. - function _postDrawCheck(uint256 _coreDisputeID, address _juror) internal view override returns (bool) { - (uint96 courtID, , , , ) = core.disputes(_coreDisputeID); - (, uint256 lockedAmountPerJuror, , , , , , , , ) = core.getRoundInfo( - _coreDisputeID, - core.getNumberOfRounds(_coreDisputeID) - 1 - ); - (uint256 staked, uint256 locked, ) = core.getJurorBalance(_juror, courtID); - (, , uint256 minStake, , , , ) = core.courts(courtID); - return staked >= locked + lockedAmountPerJuror && staked >= minStake; + /// @inheritdoc BaseDisputeKit + function _postDrawCheck(uint256 /*_coreDisputeID*/, address /*_juror*/) internal pure override returns (bool) { + return true; } } diff --git a/contracts/test/arbitration/draw.ts b/contracts/test/arbitration/draw.ts index 16de529e5..40840832b 100644 --- a/contracts/test/arbitration/draw.ts +++ b/contracts/test/arbitration/draw.ts @@ -1,6 +1,6 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { deployments, ethers, getNamedAccounts, network } from "hardhat"; -import { BigNumber } from "ethers"; +import { BigNumber, ContractTransaction, Wallet } from "ethers"; import { PNK, KlerosCore, @@ -52,11 +52,7 @@ describe("Draw Benchmark", async () => { let randomizer; beforeEach("Setup", async () => { - deployer = (await getNamedAccounts()).deployer; - relayer = (await getNamedAccounts()).relayer; - - console.log("deployer:%s", deployer); - console.log("named accounts: %O", await getNamedAccounts()); + ({ deployer, relayer } = await getNamedAccounts()); await deployments.fixture(["Arbitration", "VeaMock"], { fallbackToGlobal: true, @@ -70,9 +66,28 @@ describe("Draw Benchmark", async () => { rng = (await ethers.getContract("RandomizerRNG")) as RandomizerRNG; randomizer = (await ethers.getContract("RandomizerMock")) as RandomizerMock; sortitionModule = (await ethers.getContract("SortitionModule")) as SortitionModule; + + // CourtId 2 + const minStake = BigNumber.from(10).pow(20).mul(3); // 300 PNK + const alpha = 10000; + const feeForJuror = BigNumber.from(10).pow(17); + await core.createCourt( + 1, + false, + minStake, + alpha, + feeForJuror, + 256, + [0, 0, 0, 10], // evidencePeriod, commitPeriod, votePeriod, appealPeriod + ethers.utils.hexlify(5), // Extra data for sortition module will return the default value of K) + [1] + ); }); - it("Draw Benchmark", async () => { + type SetStake = (wallet: Wallet) => Promise; + type ExpectFromDraw = (drawTx: Promise) => Promise; + + const draw = async (setStake: SetStake, createDisputeCourtId: string, expectFromDraw: ExpectFromDraw) => { const arbitrationCost = ONE_TENTH_ETH.mul(3); const [bridger] = await ethers.getSigners(); @@ -90,7 +105,8 @@ describe("Draw Benchmark", async () => { expect(await pnk.balanceOf(wallet.address)).to.equal(ONE_THOUSAND_PNK.mul(10)); await pnk.connect(wallet).approve(core.address, ONE_THOUSAND_PNK.mul(10), { gasLimit: 300000 }); - await core.connect(wallet).setStake(1, ONE_THOUSAND_PNK.mul(10), { gasLimit: 5000000 }); + + await setStake(wallet); } // Create a dispute @@ -114,7 +130,7 @@ describe("Draw Benchmark", async () => { templateId: 0, templateUri: "", choices: 2, - extraData: "0x00", + extraData: `0x000000000000000000000000000000000000000000000000000000000000000${createDisputeCourtId}0000000000000000000000000000000000000000000000000000000000000003`, }, { value: arbitrationCost } ); @@ -131,12 +147,72 @@ describe("Draw Benchmark", async () => { await randomizer.relay(rng.address, 0, ethers.utils.randomBytes(32)); await sortitionModule.passPhase(); // Generating -> Drawing - await expect(core.draw(0, 1000, { gasLimit: 1000000 })) - .to.emit(core, "Draw") - .withArgs(anyValue, 0, 0, 0) - .to.emit(core, "Draw") - .withArgs(anyValue, 0, 0, 1) - .to.emit(core, "Draw") - .withArgs(anyValue, 0, 0, 2); + await expectFromDraw(core.draw(0, 1000, { gasLimit: 1000000 })); + }; + + it("Stakes in parent court and should draw jurors in parent court", async () => { + const setStake = async (wallet: Wallet) => { + await core.connect(wallet).setStake(1, ONE_THOUSAND_PNK.mul(5), { gasLimit: 5000000 }); + }; + + const expectFromDraw = async (drawTx: Promise) => { + await expect(drawTx) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 0) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 1) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 2); + }; + + await draw(setStake, "1", expectFromDraw); + }); + + it("Stakes in parent court and should draw nobody in subcourt", async () => { + const setStake = async (wallet: Wallet) => { + await core.connect(wallet).setStake(1, ONE_THOUSAND_PNK.mul(5), { gasLimit: 5000000 }); + }; + + const expectFromDraw = async (drawTx: Promise) => { + await expect(drawTx).to.not.emit(core, "Draw"); + }; + + await draw(setStake, "2", expectFromDraw); + }); + + it("Stakes in subcourt and should draw jurors in parent court", async () => { + const setStake = async (wallet: Wallet) => { + await core.connect(wallet).setStake(2, ONE_THOUSAND_PNK.mul(5), { gasLimit: 5000000 }); + }; + + const expectFromDraw = async (drawTx: Promise) => { + await expect(drawTx) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 0) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 1) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 2); + }; + + await draw(setStake, "1", expectFromDraw); + }); + + it("Stakes in subcourt and should draw jurors in subcourt", async () => { + const setStake = async (wallet: Wallet) => { + await core.connect(wallet).setStake(2, ONE_THOUSAND_PNK.mul(5), { gasLimit: 5000000 }); + }; + + const expectFromDraw = async (drawTx: Promise) => { + await expect(drawTx) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 0) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 1) + .to.emit(core, "Draw") + .withArgs(anyValue, 0, 0, 2); + }; + + await draw(setStake, "2", expectFromDraw); }); }); diff --git a/contracts/test/arbitration/unstake.ts b/contracts/test/arbitration/unstake.ts index 1285567ed..671fe3c80 100644 --- a/contracts/test/arbitration/unstake.ts +++ b/contracts/test/arbitration/unstake.ts @@ -31,10 +31,6 @@ describe("Unstake juror", async () => { beforeEach("Setup", async () => { ({ deployer } = await getNamedAccounts()); - - console.log("deployer:%s", deployer); - console.log("named accounts: %O", await getNamedAccounts()); - await deployments.fixture(["Arbitration"], { fallbackToGlobal: true, keepExistingDeployments: false, diff --git a/contracts/test/integration/index.ts b/contracts/test/integration/index.ts index 0dd3c6f82..86162b3ce 100644 --- a/contracts/test/integration/index.ts +++ b/contracts/test/integration/index.ts @@ -43,10 +43,6 @@ describe("Integration tests", async () => { beforeEach("Setup", async () => { ({ deployer } = await getNamedAccounts()); - - console.log("deployer:%s", deployer); - console.log("named accounts: %O", await getNamedAccounts()); - await deployments.fixture(["Arbitration", "VeaMock"], { fallbackToGlobal: true, keepExistingDeployments: false, diff --git a/cspell.json b/cspell.json index d8d3c39d1..9eb69db92 100644 --- a/cspell.json +++ b/cspell.json @@ -11,6 +11,7 @@ "words": [ "arbitrum", "autorestart", + "codegen", "commitlint", "COOLDOWN", "datetime", @@ -18,6 +19,8 @@ "Devnet", "dockerhost", "Ethfinex", + "gluegun", + "graphprotocol", "hearbeat", "IERC", "ipfs", diff --git a/subgraph/package.json b/subgraph/package.json index 339f4d348..cc9ca7499 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -26,9 +26,12 @@ "@graphprotocol/graph-ts": "^0.31.0" }, "devDependencies": { - "@graphprotocol/graph-cli": "^0.54.0", + "@graphprotocol/graph-cli": "0.52.0", "@kleros/kleros-v2-eslint-config": "workspace:^", "@kleros/kleros-v2-prettier-config": "workspace:^", "gluegun": "^5.1.2" + }, + "dependenciesComments": { + "@graphprotocol/graph-cli": "pinned because of this issue: https://github.com/graphprotocol/graph-tooling/issues/1399#issuecomment-1676104540" } } diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 7322790b5..fd19eb740 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -81,9 +81,9 @@ dataSources: name: DisputeKitClassic network: arbitrum-goerli source: - address: "0x9ddf4a70295faaA695b8CF4F22177FA1f3a1B500" + address: "0x439f92b61783A752462527f9dA9C6c6180C9253a" abi: DisputeKitClassic - startBlock: 33436570 + startBlock: 34139950 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/web/.env.testnet.public b/web/.env.testnet.public index a9170f77d..ada7c782d 100644 --- a/web/.env.testnet.public +++ b/web/.env.testnet.public @@ -1,4 +1,4 @@ # Do not enter sensitive information here. export REACT_APP_DEPLOYMENT=testnet -export REACT_APP_KLEROS_CORE_SUBGRAPH_TESTNET=https://api.thegraph.com/subgraphs/name/alcercu/kleroscoretest +export REACT_APP_KLEROS_CORE_SUBGRAPH_TESTNET=https://api.thegraph.com/subgraphs/name/kleros/kleros-v2-core-arbitrum-goerli export REACT_APP_DISPUTE_TEMPLATE_ARBGOERLI_SUBGRAPH_TESTNET=https://api.thegraph.com/subgraphs/name/alcercu/disputetemplateregistryarbgrli diff --git a/yarn.lock b/yarn.lock index d9d2fca8b..9a129a662 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3987,9 +3987,9 @@ __metadata: languageName: node linkType: hard -"@graphprotocol/graph-cli@npm:^0.54.0": - version: 0.54.0 - resolution: "@graphprotocol/graph-cli@npm:0.54.0" +"@graphprotocol/graph-cli@npm:0.52.0": + version: 0.52.0 + resolution: "@graphprotocol/graph-cli@npm:0.52.0" dependencies: "@float-capital/float-subgraph-uncrashable": ^0.0.0-alpha.4 "@oclif/core": 2.8.6 @@ -4019,7 +4019,7 @@ __metadata: yaml: 1.10.2 bin: graph: bin/run - checksum: c3bd34b26dc7e09d14e60193b806f1e513ba4fd3a0525506f015573addbb4848de21c9157426b789e99efb1850c0035aaf2d865ef7b985a9bc41884d6e45d012 + checksum: 7c6e2dbf022f4229b412e1107bb16b8e5914da2c21802af9a072a79a4f463132a192380e9c395a463c285004abedf16461037cebea7387c580c2de46200ddd40 languageName: node linkType: hard @@ -5228,7 +5228,7 @@ __metadata: version: 0.0.0-use.local resolution: "@kleros/kleros-v2-subgraph@workspace:subgraph" dependencies: - "@graphprotocol/graph-cli": ^0.54.0 + "@graphprotocol/graph-cli": 0.52.0 "@graphprotocol/graph-ts": ^0.31.0 "@kleros/kleros-v2-eslint-config": "workspace:^" "@kleros/kleros-v2-prettier-config": "workspace:^"