diff --git a/contracts/README.md b/contracts/README.md index 6677fc429..afc05510b 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -75,11 +75,13 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [DisputeKitClassicUniversity: proxy](https://sepolia.arbiscan.io/address/0xDaE66157D72Baa099cd63a833c353776206feea4), [implementation](https://sepolia.arbiscan.io/address/0xf36fa321Bb64b6E39f5DA3dbb053ccE63D077f8B) - [DisputeResolver](https://sepolia.arbiscan.io/address/0xB8B36CC43f852f9F0484f53Eb38CaBBA28a81bF6) - [DisputeResolverNeo](https://sepolia.arbiscan.io/address/0xaBC213522c01354DC0Db2B3E89bDe0FCF44Acac6) +- [DisputeResolverRuler](https://sepolia.arbiscan.io/address/0xF1544a7B9DC6aBFAbBD58A2feF8Ee8fEDdBA5DBd) - [DisputeResolverUniversity](https://sepolia.arbiscan.io/address/0x102Ba9488Df13842612e777aB16144cCACD38194) - [DisputeTemplateRegistry: proxy](https://sepolia.arbiscan.io/address/0x596D3B09E684D62217682216e9b7a0De75933391), [implementation](https://sepolia.arbiscan.io/address/0xc53b813ed94AaEb6F5518D60bf6a8109954bE3f6) - [EvidenceModule: proxy](https://sepolia.arbiscan.io/address/0x57fd453FB0d16f8ca174E7386102D7170E17Be09), [implementation](https://sepolia.arbiscan.io/address/0x05AD81f245209b7f91885fd96e57c9da90554824) - [KlerosCore: proxy](https://sepolia.arbiscan.io/address/0xA54e7A16d7460e38a8F324eF46782FB520d58CE8), [implementation](https://sepolia.arbiscan.io/address/0x91a373BBdE0532F86410682F362e2Cf685e95085) - [KlerosCoreNeo: proxy](https://sepolia.arbiscan.io/address/0x26bf077037550e437605F07e25EfcAd510715C3A), [implementation](https://sepolia.arbiscan.io/address/0x3bE96b7eAF6A3640DBa1f7CE58776D5b790B74CB) +- [KlerosCoreRuler: proxy](https://sepolia.arbiscan.io/address/0x7ffcd32A0521645E6fCFd071A68F0e26957775a5), [implementation](https://sepolia.arbiscan.io/address/0x97e30A3A940856A3913437912C746f1aF6ccC76c) - [KlerosCoreUniversity: proxy](https://sepolia.arbiscan.io/address/0x10BaAFDe8B4d3164CA781571e2F1513317f57980), [implementation](https://sepolia.arbiscan.io/address/0x8466ab62E7c923e8F2E61d0358C495676D6F939b) - [KlerosV2NeoEarlyUser](https://sepolia.arbiscan.io/address/0x0d60Ff8bbCF49Bc5352328E7E28e141834d7750F) - [PNKFaucet](https://sepolia.arbiscan.io/address/0x7EFE468003Ad6A858b5350CDE0A67bBED58739dD) diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeResolverRuler.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeResolverRuler.json new file mode 100644 index 000000000..e944e831e --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeResolverRuler.json @@ -0,0 +1,522 @@ +{ + "address": "0xF1544a7B9DC6aBFAbBD58A2feF8Ee8fEDdBA5DBd", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IArbitratorV2", + "name": "_arbitrator", + "type": "address" + }, + { + "internalType": "contract IDisputeTemplateRegistry", + "name": "_templateRegistry", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitratorV2", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_arbitrableDisputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_externalDisputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_templateId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "_templateUri", + "type": "string" + } + ], + "name": "DisputeRequest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitratorV2", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "inputs": [], + "name": "arbitrator", + "outputs": [ + { + "internalType": "contract IArbitratorV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "arbitratorDisputeIDToLocalID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitratorV2", + "name": "_arbitrator", + "type": "address" + } + ], + "name": "changeArbitrator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IDisputeTemplateRegistry", + "name": "_templateRegistry", + "type": "address" + } + ], + "name": "changeTemplateRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_arbitratorExtraData", + "type": "bytes" + }, + { + "internalType": "string", + "name": "_disputeTemplate", + "type": "string" + }, + { + "internalType": "string", + "name": "_disputeTemplateDataMappings", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_numberOfRulingOptions", + "type": "uint256" + } + ], + "name": "createDisputeForTemplate", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_arbitratorExtraData", + "type": "bytes" + }, + { + "internalType": "string", + "name": "_disputeTemplateUri", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_numberOfRulingOptions", + "type": "uint256" + } + ], + "name": "createDisputeForTemplateUri", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "disputes", + "outputs": [ + { + "internalType": "bytes", + "name": "arbitratorExtraData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "isRuled", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numberOfRulingOptions", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_arbitratorDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "rule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "templateRegistry", + "outputs": [ + { + "internalType": "contract IDisputeTemplateRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xed4584f7c576742093b97f9502be20cc868b01ccc9fc61fdbcbcc63ee6052c92", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0xF1544a7B9DC6aBFAbBD58A2feF8Ee8fEDdBA5DBd", + "transactionIndex": 1, + "gasUsed": "1052517", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf618d3e4545fcebfe9a12a9a47a97623f15f5f92d5af7126efe6848774dad51b", + "transactionHash": "0xed4584f7c576742093b97f9502be20cc868b01ccc9fc61fdbcbcc63ee6052c92", + "logs": [], + "blockNumber": 81776200, + "cumulativeGasUsed": "1052517", + "status": 1, + "byzantium": true + }, + "args": [ + "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "0x596D3B09E684D62217682216e9b7a0De75933391" + ], + "numDeployments": 2, + "solcInputHash": "2c1a31d10a5f76f480d447fbb502d6fc", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IArbitratorV2\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"internalType\":\"contract IDisputeTemplateRegistry\",\"name\":\"_templateRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitratorV2\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_arbitrableDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_externalDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_templateId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_templateUri\",\"type\":\"string\"}],\"name\":\"DisputeRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitratorV2\",\"name\":\"_arbitrator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"Ruling\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"arbitrator\",\"outputs\":[{\"internalType\":\"contract IArbitratorV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"arbitratorDisputeIDToLocalID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IArbitratorV2\",\"name\":\"_arbitrator\",\"type\":\"address\"}],\"name\":\"changeArbitrator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDisputeTemplateRegistry\",\"name\":\"_templateRegistry\",\"type\":\"address\"}],\"name\":\"changeTemplateRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_arbitratorExtraData\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"_disputeTemplate\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_disputeTemplateDataMappings\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfRulingOptions\",\"type\":\"uint256\"}],\"name\":\"createDisputeForTemplate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_arbitratorExtraData\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"_disputeTemplateUri\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfRulingOptions\",\"type\":\"uint256\"}],\"name\":\"createDisputeForTemplateUri\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"arbitratorExtraData\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"isRuled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numberOfRulingOptions\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_arbitratorDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"rule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"templateRegistry\",\"outputs\":[{\"internalType\":\"contract IDisputeTemplateRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"DisputeRequest(address,uint256,uint256,uint256,string)\":{\"details\":\"To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\",\"params\":{\"_arbitrableDisputeID\":\"The identifier of the dispute in the Arbitrable contract.\",\"_arbitrator\":\"The arbitrator of the contract.\",\"_externalDisputeID\":\"An identifier created outside Kleros by the protocol requesting arbitration.\",\"_templateId\":\"The identifier of the dispute template. Should not be used with _templateUri.\",\"_templateUri\":\"The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\"}},\"Ruling(address,uint256,uint256)\":{\"details\":\"To be raised when a ruling is given.\",\"params\":{\"_arbitrator\":\"The arbitrator giving the ruling.\",\"_disputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_ruling\":\"The ruling which was given.\"}}},\"kind\":\"dev\",\"methods\":{\"changeGovernor(address)\":{\"details\":\"Changes the governor.\",\"params\":{\"_governor\":\"The address of the new governor.\"}},\"constructor\":{\"details\":\"Constructor\",\"params\":{\"_arbitrator\":\"Target global arbitrator for any disputes.\"}},\"createDisputeForTemplate(bytes,string,string,uint256)\":{\"details\":\"Calls createDispute function of the specified arbitrator to create a dispute. Note that we don\\u2019t need to check that msg.value is enough to pay arbitration fees as it\\u2019s the responsibility of the arbitrator contract.\",\"params\":{\"_arbitratorExtraData\":\"Extra data for the arbitrator of the dispute.\",\"_disputeTemplate\":\"Dispute template.\",\"_disputeTemplateDataMappings\":\"The data mappings.\",\"_numberOfRulingOptions\":\"Number of ruling options.\"},\"returns\":{\"disputeID\":\"Dispute id (on arbitrator side) of the created dispute.\"}},\"createDisputeForTemplateUri(bytes,string,uint256)\":{\"details\":\"Calls createDispute function of the specified arbitrator to create a dispute. Note that we don\\u2019t need to check that msg.value is enough to pay arbitration fees as it\\u2019s the responsibility of the arbitrator contract.\",\"params\":{\"_arbitratorExtraData\":\"Extra data for the arbitrator of the dispute.\",\"_disputeTemplateUri\":\"The URI to the dispute template. For example on IPFS: starting with '/ipfs/'.\",\"_numberOfRulingOptions\":\"Number of ruling options.\"},\"returns\":{\"disputeID\":\"Dispute id (on arbitrator side) of the created dispute.\"}},\"rule(uint256,uint256)\":{\"details\":\"To be called by the arbitrator of the dispute, to declare the winning ruling.\",\"params\":{\"_arbitratorDisputeID\":\"ID of the dispute in arbitrator contract.\",\"_ruling\":\"The ruling choice of the arbitration.\"}}},\"title\":\"DisputeResolverRuler It extends DisputeResolver for testing purposes of the automatic ruling modes. The arbitrator disputeID must be known before dispute creation, otherwise the dispute cannot be retrieved during the immediate call to rule().\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/devtools/DisputeResolverRuler.sol\":\"DisputeResolverRuler\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\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 value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"src/arbitration/arbitrables/DisputeResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"../interfaces/IArbitrableV2.sol\\\";\\nimport \\\"../interfaces/IDisputeTemplateRegistry.sol\\\";\\n\\npragma solidity 0.8.24;\\n\\n/// @title DisputeResolver\\n/// DisputeResolver contract adapted for V2 from https://github.com/kleros/arbitrable-proxy-contracts/blob/master/contracts/ArbitrableProxy.sol.\\ncontract DisputeResolver is IArbitrableV2 {\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n struct DisputeStruct {\\n bytes arbitratorExtraData; // Extra data for the dispute.\\n bool isRuled; // True if the dispute has been ruled.\\n uint256 ruling; // Ruling given to the dispute.\\n uint256 numberOfRulingOptions; // The number of choices the arbitrator can give.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n address public governor; // The governor.\\n IArbitratorV2 public arbitrator; // The arbitrator.\\n IDisputeTemplateRegistry public templateRegistry; // The dispute template registry.\\n DisputeStruct[] public disputes; // Local disputes.\\n mapping(uint256 => uint256) public arbitratorDisputeIDToLocalID; // Maps arbitrator-side dispute IDs to local dispute IDs.\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Constructor\\n /// @param _arbitrator Target global arbitrator for any disputes.\\n constructor(IArbitratorV2 _arbitrator, IDisputeTemplateRegistry _templateRegistry) {\\n governor = msg.sender;\\n arbitrator = _arbitrator;\\n templateRegistry = _templateRegistry;\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Changes the governor.\\n /// @param _governor The address of the new governor.\\n function changeGovernor(address _governor) external {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n governor = _governor;\\n }\\n\\n function changeArbitrator(IArbitratorV2 _arbitrator) external {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n arbitrator = _arbitrator;\\n }\\n\\n function changeTemplateRegistry(IDisputeTemplateRegistry _templateRegistry) external {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n templateRegistry = _templateRegistry;\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Calls createDispute function of the specified arbitrator to create a dispute.\\n /// Note that we don\\u2019t need to check that msg.value is enough to pay arbitration fees as it\\u2019s the responsibility of the arbitrator contract.\\n /// @param _arbitratorExtraData Extra data for the arbitrator of the dispute.\\n /// @param _disputeTemplate Dispute template.\\n /// @param _disputeTemplateDataMappings The data mappings.\\n /// @param _numberOfRulingOptions Number of ruling options.\\n /// @return disputeID Dispute id (on arbitrator side) of the created dispute.\\n function createDisputeForTemplate(\\n bytes calldata _arbitratorExtraData,\\n string calldata _disputeTemplate,\\n string memory _disputeTemplateDataMappings,\\n uint256 _numberOfRulingOptions\\n ) external payable returns (uint256 disputeID) {\\n return\\n _createDispute(\\n _arbitratorExtraData,\\n _disputeTemplate,\\n _disputeTemplateDataMappings,\\n \\\"\\\",\\n _numberOfRulingOptions\\n );\\n }\\n\\n /// @dev Calls createDispute function of the specified arbitrator to create a dispute.\\n /// Note that we don\\u2019t need to check that msg.value is enough to pay arbitration fees as it\\u2019s the responsibility of the arbitrator contract.\\n /// @param _arbitratorExtraData Extra data for the arbitrator of the dispute.\\n /// @param _disputeTemplateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'.\\n /// @param _numberOfRulingOptions Number of ruling options.\\n /// @return disputeID Dispute id (on arbitrator side) of the created dispute.\\n function createDisputeForTemplateUri(\\n bytes calldata _arbitratorExtraData,\\n string calldata _disputeTemplateUri,\\n uint256 _numberOfRulingOptions\\n ) external payable returns (uint256 disputeID) {\\n return _createDispute(_arbitratorExtraData, \\\"\\\", \\\"\\\", _disputeTemplateUri, _numberOfRulingOptions);\\n }\\n\\n /// @dev To be called by the arbitrator of the dispute, to declare the winning ruling.\\n /// @param _arbitratorDisputeID ID of the dispute in arbitrator contract.\\n /// @param _ruling The ruling choice of the arbitration.\\n function rule(uint256 _arbitratorDisputeID, uint256 _ruling) external override {\\n uint256 localDisputeID = arbitratorDisputeIDToLocalID[_arbitratorDisputeID];\\n DisputeStruct storage dispute = disputes[localDisputeID];\\n require(msg.sender == address(arbitrator), \\\"Only the arbitrator can execute this.\\\");\\n require(_ruling <= dispute.numberOfRulingOptions, \\\"Invalid ruling.\\\");\\n require(!dispute.isRuled, \\\"This dispute has been ruled already.\\\");\\n\\n dispute.isRuled = true;\\n dispute.ruling = _ruling;\\n\\n emit Ruling(IArbitratorV2(msg.sender), _arbitratorDisputeID, dispute.ruling);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n function _createDispute(\\n bytes calldata _arbitratorExtraData,\\n string memory _disputeTemplate,\\n string memory _disputeTemplateDataMappings,\\n string memory _disputeTemplateUri,\\n uint256 _numberOfRulingOptions\\n ) internal virtual returns (uint256 disputeID) {\\n require(_numberOfRulingOptions > 1, \\\"Should be at least 2 ruling options.\\\");\\n\\n disputeID = arbitrator.createDispute{value: msg.value}(_numberOfRulingOptions, _arbitratorExtraData);\\n uint256 localDisputeID = disputes.length;\\n disputes.push(\\n DisputeStruct({\\n arbitratorExtraData: _arbitratorExtraData,\\n isRuled: false,\\n ruling: 0,\\n numberOfRulingOptions: _numberOfRulingOptions\\n })\\n );\\n arbitratorDisputeIDToLocalID[disputeID] = localDisputeID;\\n uint256 templateId = templateRegistry.setDisputeTemplate(\\\"\\\", _disputeTemplate, _disputeTemplateDataMappings);\\n emit DisputeRequest(arbitrator, localDisputeID, localDisputeID, templateId, _disputeTemplateUri);\\n }\\n}\\n\",\"keccak256\":\"0x48f3aa7fad24ef68821c57c5741189eb5c73bc9a915ee8df2073b1aa844423f2\",\"license\":\"MIT\"},\"src/arbitration/devtools/DisputeResolverRuler.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/// @custom:authors: [@unknownunknown1, @jaybuidl]\\n/// @custom:reviewers: []\\n/// @custom:auditors: []\\n/// @custom:bounties: []\\n\\nimport {DisputeResolver, IArbitratorV2, IDisputeTemplateRegistry} from \\\"../arbitrables/DisputeResolver.sol\\\";\\n\\npragma solidity 0.8.24;\\n\\ninterface IKlerosCoreRulerFragment {\\n function getNextDisputeID() external view returns (uint256);\\n}\\n\\n/// @title DisputeResolverRuler\\n/// It extends DisputeResolver for testing purposes of the automatic ruling modes.\\n/// The arbitrator disputeID must be known before dispute creation, otherwise the dispute cannot be retrieved during the immediate call to rule().\\ncontract DisputeResolverRuler is DisputeResolver {\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Constructor\\n /// @param _arbitrator Target global arbitrator for any disputes.\\n constructor(\\n IArbitratorV2 _arbitrator,\\n IDisputeTemplateRegistry _templateRegistry\\n ) DisputeResolver(_arbitrator, _templateRegistry) {\\n governor = msg.sender;\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n function _createDispute(\\n bytes calldata _arbitratorExtraData,\\n string memory _disputeTemplate,\\n string memory _disputeTemplateDataMappings,\\n string memory _disputeTemplateUri,\\n uint256 _numberOfRulingOptions\\n ) internal override returns (uint256 disputeID) {\\n require(_numberOfRulingOptions > 1, \\\"Should be at least 2 ruling options.\\\");\\n\\n uint256 localDisputeID = disputes.length;\\n DisputeStruct storage dispute = disputes.push();\\n dispute.arbitratorExtraData = _arbitratorExtraData;\\n dispute.numberOfRulingOptions = _numberOfRulingOptions;\\n\\n // Keep track of the upcoming dispute ID before dispute creation, so rule() can be called immediately after.\\n disputeID = IKlerosCoreRulerFragment(address(arbitrator)).getNextDisputeID();\\n arbitratorDisputeIDToLocalID[disputeID] = localDisputeID;\\n uint256 templateId = templateRegistry.setDisputeTemplate(\\\"\\\", _disputeTemplate, _disputeTemplateDataMappings);\\n emit DisputeRequest(arbitrator, localDisputeID, localDisputeID, templateId, _disputeTemplateUri);\\n\\n arbitrator.createDispute{value: msg.value}(_numberOfRulingOptions, _arbitratorExtraData);\\n }\\n}\\n\",\"keccak256\":\"0x0d3220eb3828a612bf342bf5987a3fbba33a74e5a033be7152e7aa3c56476328\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _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\":\"0xf28c04c5c537d4f2faa02b03c389b6932a8b7061ae6fca91be8db53191c941f6\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeTemplateRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title IDisputeTemplate\\n/// @notice Dispute Template interface.\\ninterface IDisputeTemplateRegistry {\\n /// @dev To be emitted when a new dispute template is created.\\n /// @param _templateId The identifier of the dispute template.\\n /// @param _templateTag An optional tag for the dispute template, such as \\\"registration\\\" or \\\"removal\\\".\\n /// @param _templateData The template data.\\n /// @param _templateDataMappings The data mappings.\\n event DisputeTemplate(\\n uint256 indexed _templateId,\\n string indexed _templateTag,\\n string _templateData,\\n string _templateDataMappings\\n );\\n\\n function setDisputeTemplate(\\n string memory _templateTag,\\n string memory _templateData,\\n string memory _templateDataMappings\\n ) external returns (uint256 templateId);\\n}\\n\",\"keccak256\":\"0xb46ff71c32a524a865fe8ca99d94c9daeb690bc9d7d49d963a45b06f60af19f3\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561000f575f80fd5b50604051610e85380380610e8583398101604081905261002e91610088565b5f8054600180546001600160a01b03199081166001600160a01b0396871617909155600280548216949095169390931790935591811633918216171790556100c0565b6001600160a01b0381168114610085575f80fd5b50565b5f8060408385031215610099575f80fd5b82516100a481610071565b60208401519092506100b581610071565b809150509250929050565b610db8806100cd5f395ff3fe60806040526004361061009a575f3560e01c8063908bb29511610062578063908bb29514610167578063a0af81f014610188578063dc653511146101a7578063e09997d9146101ba578063e4c0aaf4146101e5578063fc548f0814610204575f80fd5b80630c340a241461009e578063311a6c56146100d95780634660ebbe146100fa578063564a565d146101195780636cc6cde114610148575b5f80fd5b3480156100a9575f80fd5b505f546100bc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100e4575f80fd5b506100f86100f336600461089e565b610223565b005b348015610105575f80fd5b506100f86101143660046108d5565b6103c1565b348015610124575f80fd5b506101386101333660046108f7565b61040c565b6040516100d09493929190610951565b348015610153575f80fd5b506001546100bc906001600160a01b031681565b61017a6101753660046109c4565b6104d3565b6040519081526020016100d0565b348015610193575f80fd5b506002546100bc906001600160a01b031681565b61017a6101b5366004610a46565b61053e565b3480156101c5575f80fd5b5061017a6101d43660046108f7565b60046020525f908152604090205481565b3480156101f0575f80fd5b506100f86101ff3660046108d5565b61059b565b34801561020f575f80fd5b506100f861021e3660046108d5565b6105e5565b5f82815260046020526040812054600380549192918390811061024857610248610b4a565b5f918252602090912060015460049092020191506001600160a01b031633146102c65760405162461bcd60e51b815260206004820152602560248201527f4f6e6c79207468652061726269747261746f722063616e2065786563757465206044820152643a3434b99760d91b60648201526084015b60405180910390fd5b806003015483111561030c5760405162461bcd60e51b815260206004820152600f60248201526e24b73b30b634b210393ab634b7339760891b60448201526064016102bd565b600181015460ff161561036d5760405162461bcd60e51b8152602060048201526024808201527f54686973206469737075746520686173206265656e2072756c656420616c726560448201526330b23c9760e11b60648201526084016102bd565b6001818101805460ff1916909117905560028101839055604051838152849033907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769060200160405180910390a350505050565b5f546001600160a01b031633146103ea5760405162461bcd60e51b81526004016102bd90610b5e565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6003818154811061041b575f80fd5b905f5260205f2090600402015f91509050805f01805461043a90610ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461046690610ba0565b80156104b15780601f10610488576101008083540402835291602001916104b1565b820191905f5260205f20905b81548152906001019060200180831161049457829003601f168201915b5050505060018301546002840154600390940154929360ff9091169290915084565b5f610534868660405180602001604052805f81525060405180602001604052805f81525088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508a9250610630915050565b9695505050505050565b5f610590878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92018290525060408051602081019091529081528a93509150889050610630565b979650505050505050565b5f546001600160a01b031633146105c45760405162461bcd60e51b81526004016102bd90610b5e565b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b0316331461060e5760405162461bcd60e51b81526004016102bd90610b5e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f6001821161068d5760405162461bcd60e51b8152602060048201526024808201527f53686f756c64206265206174206c6561737420322072756c696e67206f70746960448201526337b7399760e11b60648201526084016102bd565b600380546001810182555f91909152600481027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01806106ce898b83610c24565b50600381018490556001546040805163db8a173b60e01b815290516001600160a01b039092169163db8a173b916004808201926020929091908290030181865afa15801561071e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107429190610cde565b5f81815260046020819052604080832086905560025490516312a6505d60e21b815293965091926001600160a01b0390921691634a99417491610789918c918c9101610cf5565b6020604051808303815f875af11580156107a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107c99190610cde565b60015460405191925084916001600160a01b03909116907f8bd32f430ff060e6bd204709b3790c9807987263d3230c580dc80b5f89e271869061081190849086908c90610d2f565b60405180910390a360015460405163c13517e160e01b81526001600160a01b039091169063c13517e190349061084f9089908f908f90600401610d4d565b60206040518083038185885af115801561086b573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906108909190610cde565b505050509695505050505050565b5f80604083850312156108af575f80fd5b50508035926020909101359150565b6001600160a01b03811681146108d2575f80fd5b50565b5f602082840312156108e5575f80fd5b81356108f0816108be565b9392505050565b5f60208284031215610907575f80fd5b5035919050565b5f81518084525f5b8181101561093257602081850181015186830182015201610916565b505f602082860101526020601f19601f83011685010191505092915050565b608081525f610963608083018761090e565b9415156020830152506040810192909252606090910152919050565b5f8083601f84011261098f575f80fd5b50813567ffffffffffffffff8111156109a6575f80fd5b6020830191508360208285010111156109bd575f80fd5b9250929050565b5f805f805f606086880312156109d8575f80fd5b853567ffffffffffffffff808211156109ef575f80fd5b6109fb89838a0161097f565b90975095506020880135915080821115610a13575f80fd5b50610a208882890161097f565b96999598509660400135949350505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f805f8060808789031215610a5b575f80fd5b863567ffffffffffffffff80821115610a72575f80fd5b610a7e8a838b0161097f565b90985096506020890135915080821115610a96575f80fd5b610aa28a838b0161097f565b90965094506040890135915080821115610aba575f80fd5b818901915089601f830112610acd575f80fd5b813581811115610adf57610adf610a32565b604051601f8201601f19908116603f01168101908382118183101715610b0757610b07610a32565b816040528281528c6020848701011115610b1f575f80fd5b826020860160208301375f602084830101528096505050505050606087013590509295509295509295565b634e487b7160e01b5f52603260045260245ffd5b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b600181811c90821680610bb457607f821691505b602082108103610bd257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610c1f57805f5260205f20601f840160051c81016020851015610bfd5750805b601f840160051c820191505b81811015610c1c575f8155600101610c09565b50505b505050565b67ffffffffffffffff831115610c3c57610c3c610a32565b610c5083610c4a8354610ba0565b83610bd8565b5f601f841160018114610c81575f8515610c6a5750838201355b5f19600387901b1c1916600186901b178355610c1c565b5f83815260208120601f198716915b82811015610cb05786850135825560209485019460019092019101610c90565b5086821015610ccc575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215610cee575f80fd5b5051919050565b606081525f6060820152608060208201525f610d14608083018561090e565b8281036040840152610d26818561090e565b95945050505050565b838152826020820152606060408201525f610d26606083018461090e565b83815260406020820152816040820152818360608301375f818301606090810191909152601f909201601f191601019291505056fea26469706673582212203eda6a65729647e2f60a62845af3d173c2f828e3697f51e60b96d5fbf52f70ec64736f6c63430008180033", + "deployedBytecode": "0x60806040526004361061009a575f3560e01c8063908bb29511610062578063908bb29514610167578063a0af81f014610188578063dc653511146101a7578063e09997d9146101ba578063e4c0aaf4146101e5578063fc548f0814610204575f80fd5b80630c340a241461009e578063311a6c56146100d95780634660ebbe146100fa578063564a565d146101195780636cc6cde114610148575b5f80fd5b3480156100a9575f80fd5b505f546100bc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100e4575f80fd5b506100f86100f336600461089e565b610223565b005b348015610105575f80fd5b506100f86101143660046108d5565b6103c1565b348015610124575f80fd5b506101386101333660046108f7565b61040c565b6040516100d09493929190610951565b348015610153575f80fd5b506001546100bc906001600160a01b031681565b61017a6101753660046109c4565b6104d3565b6040519081526020016100d0565b348015610193575f80fd5b506002546100bc906001600160a01b031681565b61017a6101b5366004610a46565b61053e565b3480156101c5575f80fd5b5061017a6101d43660046108f7565b60046020525f908152604090205481565b3480156101f0575f80fd5b506100f86101ff3660046108d5565b61059b565b34801561020f575f80fd5b506100f861021e3660046108d5565b6105e5565b5f82815260046020526040812054600380549192918390811061024857610248610b4a565b5f918252602090912060015460049092020191506001600160a01b031633146102c65760405162461bcd60e51b815260206004820152602560248201527f4f6e6c79207468652061726269747261746f722063616e2065786563757465206044820152643a3434b99760d91b60648201526084015b60405180910390fd5b806003015483111561030c5760405162461bcd60e51b815260206004820152600f60248201526e24b73b30b634b210393ab634b7339760891b60448201526064016102bd565b600181015460ff161561036d5760405162461bcd60e51b8152602060048201526024808201527f54686973206469737075746520686173206265656e2072756c656420616c726560448201526330b23c9760e11b60648201526084016102bd565b6001818101805460ff1916909117905560028101839055604051838152849033907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769060200160405180910390a350505050565b5f546001600160a01b031633146103ea5760405162461bcd60e51b81526004016102bd90610b5e565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6003818154811061041b575f80fd5b905f5260205f2090600402015f91509050805f01805461043a90610ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461046690610ba0565b80156104b15780601f10610488576101008083540402835291602001916104b1565b820191905f5260205f20905b81548152906001019060200180831161049457829003601f168201915b5050505060018301546002840154600390940154929360ff9091169290915084565b5f610534868660405180602001604052805f81525060405180602001604052805f81525088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508a9250610630915050565b9695505050505050565b5f610590878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92018290525060408051602081019091529081528a93509150889050610630565b979650505050505050565b5f546001600160a01b031633146105c45760405162461bcd60e51b81526004016102bd90610b5e565b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b0316331461060e5760405162461bcd60e51b81526004016102bd90610b5e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f6001821161068d5760405162461bcd60e51b8152602060048201526024808201527f53686f756c64206265206174206c6561737420322072756c696e67206f70746960448201526337b7399760e11b60648201526084016102bd565b600380546001810182555f91909152600481027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01806106ce898b83610c24565b50600381018490556001546040805163db8a173b60e01b815290516001600160a01b039092169163db8a173b916004808201926020929091908290030181865afa15801561071e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107429190610cde565b5f81815260046020819052604080832086905560025490516312a6505d60e21b815293965091926001600160a01b0390921691634a99417491610789918c918c9101610cf5565b6020604051808303815f875af11580156107a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107c99190610cde565b60015460405191925084916001600160a01b03909116907f8bd32f430ff060e6bd204709b3790c9807987263d3230c580dc80b5f89e271869061081190849086908c90610d2f565b60405180910390a360015460405163c13517e160e01b81526001600160a01b039091169063c13517e190349061084f9089908f908f90600401610d4d565b60206040518083038185885af115801561086b573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906108909190610cde565b505050509695505050505050565b5f80604083850312156108af575f80fd5b50508035926020909101359150565b6001600160a01b03811681146108d2575f80fd5b50565b5f602082840312156108e5575f80fd5b81356108f0816108be565b9392505050565b5f60208284031215610907575f80fd5b5035919050565b5f81518084525f5b8181101561093257602081850181015186830182015201610916565b505f602082860101526020601f19601f83011685010191505092915050565b608081525f610963608083018761090e565b9415156020830152506040810192909252606090910152919050565b5f8083601f84011261098f575f80fd5b50813567ffffffffffffffff8111156109a6575f80fd5b6020830191508360208285010111156109bd575f80fd5b9250929050565b5f805f805f606086880312156109d8575f80fd5b853567ffffffffffffffff808211156109ef575f80fd5b6109fb89838a0161097f565b90975095506020880135915080821115610a13575f80fd5b50610a208882890161097f565b96999598509660400135949350505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f805f8060808789031215610a5b575f80fd5b863567ffffffffffffffff80821115610a72575f80fd5b610a7e8a838b0161097f565b90985096506020890135915080821115610a96575f80fd5b610aa28a838b0161097f565b90965094506040890135915080821115610aba575f80fd5b818901915089601f830112610acd575f80fd5b813581811115610adf57610adf610a32565b604051601f8201601f19908116603f01168101908382118183101715610b0757610b07610a32565b816040528281528c6020848701011115610b1f575f80fd5b826020860160208301375f602084830101528096505050505050606087013590509295509295509295565b634e487b7160e01b5f52603260045260245ffd5b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b600181811c90821680610bb457607f821691505b602082108103610bd257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610c1f57805f5260205f20601f840160051c81016020851015610bfd5750805b601f840160051c820191505b81811015610c1c575f8155600101610c09565b50505b505050565b67ffffffffffffffff831115610c3c57610c3c610a32565b610c5083610c4a8354610ba0565b83610bd8565b5f601f841160018114610c81575f8515610c6a5750838201355b5f19600387901b1c1916600186901b178355610c1c565b5f83815260208120601f198716915b82811015610cb05786850135825560209485019460019092019101610c90565b5086821015610ccc575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215610cee575f80fd5b5051919050565b606081525f6060820152608060208201525f610d14608083018561090e565b8281036040840152610d26818561090e565b95945050505050565b838152826020820152606060408201525f610d26606083018461090e565b83815260406020820152816040820152818360608301375f818301606090810191909152601f909201601f191601019291505056fea26469706673582212203eda6a65729647e2f60a62845af3d173c2f828e3697f51e60b96d5fbf52f70ec64736f6c63430008180033", + "devdoc": { + "events": { + "DisputeRequest(address,uint256,uint256,uint256,string)": { + "details": "To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.", + "params": { + "_arbitrableDisputeID": "The identifier of the dispute in the Arbitrable contract.", + "_arbitrator": "The arbitrator of the contract.", + "_externalDisputeID": "An identifier created outside Kleros by the protocol requesting arbitration.", + "_templateId": "The identifier of the dispute template. Should not be used with _templateUri.", + "_templateUri": "The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId." + } + }, + "Ruling(address,uint256,uint256)": { + "details": "To be raised when a ruling is given.", + "params": { + "_arbitrator": "The arbitrator giving the ruling.", + "_disputeID": "The identifier of the dispute in the Arbitrator contract.", + "_ruling": "The ruling which was given." + } + } + }, + "kind": "dev", + "methods": { + "changeGovernor(address)": { + "details": "Changes the governor.", + "params": { + "_governor": "The address of the new governor." + } + }, + "constructor": { + "details": "Constructor", + "params": { + "_arbitrator": "Target global arbitrator for any disputes." + } + }, + "createDisputeForTemplate(bytes,string,string,uint256)": { + "details": "Calls createDispute function of the specified arbitrator to create a dispute. Note that we don’t need to check that msg.value is enough to pay arbitration fees as it’s the responsibility of the arbitrator contract.", + "params": { + "_arbitratorExtraData": "Extra data for the arbitrator of the dispute.", + "_disputeTemplate": "Dispute template.", + "_disputeTemplateDataMappings": "The data mappings.", + "_numberOfRulingOptions": "Number of ruling options." + }, + "returns": { + "disputeID": "Dispute id (on arbitrator side) of the created dispute." + } + }, + "createDisputeForTemplateUri(bytes,string,uint256)": { + "details": "Calls createDispute function of the specified arbitrator to create a dispute. Note that we don’t need to check that msg.value is enough to pay arbitration fees as it’s the responsibility of the arbitrator contract.", + "params": { + "_arbitratorExtraData": "Extra data for the arbitrator of the dispute.", + "_disputeTemplateUri": "The URI to the dispute template. For example on IPFS: starting with '/ipfs/'.", + "_numberOfRulingOptions": "Number of ruling options." + }, + "returns": { + "disputeID": "Dispute id (on arbitrator side) of the created dispute." + } + }, + "rule(uint256,uint256)": { + "details": "To be called by the arbitrator of the dispute, to declare the winning ruling.", + "params": { + "_arbitratorDisputeID": "ID of the dispute in arbitrator contract.", + "_ruling": "The ruling choice of the arbitration." + } + } + }, + "title": "DisputeResolverRuler It extends DisputeResolver for testing purposes of the automatic ruling modes. The arbitrator disputeID must be known before dispute creation, otherwise the dispute cannot be retrieved during the immediate call to rule().", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 13605, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 13608, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "arbitrator", + "offset": 0, + "slot": "1", + "type": "t_contract(IArbitratorV2)21658" + }, + { + "astId": 13611, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "templateRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IDisputeTemplateRegistry)21829" + }, + { + "astId": 13615, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "disputes", + "offset": 0, + "slot": "3", + "type": "t_array(t_struct(DisputeStruct)13603_storage)dyn_storage" + }, + { + "astId": 13619, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "arbitratorDisputeIDToLocalID", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(DisputeStruct)13603_storage)dyn_storage": { + "base": "t_struct(DisputeStruct)13603_storage", + "encoding": "dynamic_array", + "label": "struct DisputeResolver.DisputeStruct[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes_storage": { + "encoding": "bytes", + "label": "bytes", + "numberOfBytes": "32" + }, + "t_contract(IArbitratorV2)21658": { + "encoding": "inplace", + "label": "contract IArbitratorV2", + "numberOfBytes": "20" + }, + "t_contract(IDisputeTemplateRegistry)21829": { + "encoding": "inplace", + "label": "contract IDisputeTemplateRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(DisputeStruct)13603_storage": { + "encoding": "inplace", + "label": "struct DisputeResolver.DisputeStruct", + "members": [ + { + "astId": 13596, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "arbitratorExtraData", + "offset": 0, + "slot": "0", + "type": "t_bytes_storage" + }, + { + "astId": 13598, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "isRuled", + "offset": 0, + "slot": "1", + "type": "t_bool" + }, + { + "astId": 13600, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "ruling", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 13602, + "contract": "src/arbitration/devtools/DisputeResolverRuler.sol:DisputeResolverRuler", + "label": "numberOfRulingOptions", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler.json b/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler.json new file mode 100644 index 000000000..adb4c6b54 --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler.json @@ -0,0 +1,1617 @@ +{ + "address": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "abi": [ + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AppealFeesNotEnough", + "type": "error" + }, + { + "inputs": [], + "name": "ArbitrationFeesNotEnough", + "type": "error" + }, + { + "inputs": [], + "name": "DisputeNotAppealable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedDelegateCall", + "type": "error" + }, + { + "inputs": [], + "name": "GovernorOnly", + "type": "error" + }, + { + "inputs": [], + "name": "GovernorOrInstructorOnly", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidForkingCourtAsParent", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "NoRulerSet", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "RulerOnly", + "type": "error" + }, + { + "inputs": [], + "name": "RulingAlreadyExecuted", + "type": "error" + }, + { + "inputs": [], + "name": "RulingModeNotSet", + "type": "error" + }, + { + "inputs": [], + "name": "TokenNotAccepted", + "type": "error" + }, + { + "inputs": [], + "name": "TransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [], + "name": "UnsuccessfulCall", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "_accepted", + "type": "bool" + } + ], + "name": "AcceptedFeeToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "AppealDecision", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "AppealPossible", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "indexed": true, + "internalType": "enum KlerosCoreRuler.RulingMode", + "name": "mode", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "overridden", + "type": "bool" + } + ], + "name": "AutoRuled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_courtID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint96", + "name": "_parent", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "CourtCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_roundID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint96", + "name": "_fromCourtID", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "_toCourtID", + "type": "uint96" + } + ], + "name": "CourtJump", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "_courtID", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "CourtModified", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "DisputeCreation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_roundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_pnkAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + } + ], + "name": "LeftoverRewardSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_rateInEth", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "_rateDecimals", + "type": "uint8" + } + ], + "name": "NewCurrencyRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum KlerosCoreRuler.Period", + "name": "_period", + "type": "uint8" + } + ], + "name": "NewPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_oldRuler", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newRuler", + "type": "address" + } + ], + "name": "RulerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum KlerosCoreRuler.RulingMode", + "name": "rulingMode", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "presetRuling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "presetTied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "presetOverridden", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct KlerosCoreRuler.RulerSettings", + "name": "_settings", + "type": "tuple" + } + ], + "name": "RulerSettingsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_roundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_degreeOfCoherency", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "_pnkAmount", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "_feeAmount", + "type": "int256" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + } + ], + "name": "TokenAndETHShift", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "_jump", + "type": "bool" + } + ], + "name": "appeal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_jump", + "type": "bool" + } + ], + "name": "appealCost", + "outputs": [ + { + "internalType": "uint256", + "name": "cost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + }, + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + } + ], + "name": "arbitrationCost", + "outputs": [ + { + "internalType": "uint256", + "name": "cost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "arbitrationCost", + "outputs": [ + { + "internalType": "uint256", + "name": "cost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_accepted", + "type": "bool" + } + ], + "name": "changeAcceptedFeeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "_courtID", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "changeCourtParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "uint64", + "name": "_rateInEth", + "type": "uint64" + }, + { + "internalType": "uint8", + "name": "_rateDecimals", + "type": "uint8" + } + ], + "name": "changeCurrencyRates", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_pinakion", + "type": "address" + } + ], + "name": "changePinakion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "internalType": "address", + "name": "_newRuler", + "type": "address" + } + ], + "name": "changeRuler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_presetRuling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_presetTied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_presetOverridden", + "type": "bool" + } + ], + "name": "changeRulingModeToAutomaticPreset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "changeRulingModeToAutomaticRandom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "changeRulingModeToManual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amountInEth", + "type": "uint256" + } + ], + "name": "convertEthToTokenAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "courts", + "outputs": [ + { + "internalType": "uint96", + "name": "parent", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "hiddenVotes", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "minStake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alpha", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeForJuror", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "jurorsForCourtJump", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "disabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "_parent", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "createCourt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "createDispute", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + }, + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_feeAmount", + "type": "uint256" + } + ], + "name": "createDispute", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "currencyRates", + "outputs": [ + { + "internalType": "bool", + "name": "feePaymentAccepted", + "type": "bool" + }, + { + "internalType": "uint64", + "name": "rateInEth", + "type": "uint64" + }, + { + "internalType": "uint8", + "name": "rateDecimals", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "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": "uint96", + "name": "courtID", + "type": "uint96" + }, + { + "internalType": "contract IArbitrableV2", + "name": "arbitrated", + "type": "address" + }, + { + "internalType": "enum KlerosCoreRuler.Period", + "name": "period", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "ruled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_round", + "type": "uint256" + } + ], + "name": "execute", + "outputs": [], + "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": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "overridden", + "type": "bool" + } + ], + "name": "executeRuling", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNextDisputeID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + } + ], + "name": "getNumberOfRounds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + } + ], + "name": "getNumberOfVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_round", + "type": "uint256" + } + ], + "name": "getRoundInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "totalFeesForJurors", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sumFeeRewardPaid", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "feeToken", + "type": "address" + } + ], + "internalType": "struct KlerosCoreRuler.Round", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "_courtID", + "type": "uint96" + } + ], + "name": "getTimesPerPeriod", + "outputs": [ + { + "internalType": "uint256[4]", + "name": "timesPerPeriod", + "type": "uint256[4]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_pinakion", + "type": "address" + }, + { + "internalType": "uint256[4]", + "name": "_courtParameters", + "type": "uint256[4]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pinakion", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "arbitrable", + "type": "address" + } + ], + "name": "rulers", + "outputs": [ + { + "internalType": "address", + "name": "ruler", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "name": "rulingResults", + "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": "contract IArbitrableV2", + "name": "arbitrable", + "type": "address" + } + ], + "name": "settings", + "outputs": [ + { + "internalType": "enum KlerosCoreRuler.RulingMode", + "name": "rulingMode", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "presetRuling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "presetTied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "presetOverridden", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "transactionIndex": 1, + "gasUsed": "366202", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000040000000000000100005000000000000000000000000000040008000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000060000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4a74c33b3212cc7ed833956036b191ca451ae191619b2e4f90cf6dad50868d33", + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 81776148, + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "address": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "topics": [ + "0x0c907a651f88974ed0d9423aacc8b998c40eedf39920e2c3bdae0adcc486a761", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0x4a74c33b3212cc7ed833956036b191ca451ae191619b2e4f90cf6dad50868d33" + }, + { + "transactionIndex": 1, + "blockNumber": 81776148, + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "address": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 1, + "blockHash": "0x4a74c33b3212cc7ed833956036b191ca451ae191619b2e4f90cf6dad50868d33" + } + ], + "blockNumber": 81776148, + "cumulativeGasUsed": "366202", + "status": 1, + "byzantium": true + }, + "args": [ + "0x97e30A3A940856A3913437912C746f1aF6ccC76c", + "0x05d3177d000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c5900000000000000000000000034b944d42cacfc8266955d07a80181d2054aa22500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000010" + ], + "numDeployments": 1, + "solcInputHash": "2c1a31d10a5f76f480d447fbb502d6fc", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Simon Malatrait \",\"details\":\"This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Initializes the upgradeable proxy with an initial implementation specified by `_implementation`. If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\"}},\"stateVariables\":{\"IMPLEMENTATION_SLOT\":{\"details\":\"Storage slot with the address of the current implementation. This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is validated in the constructor. NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\"}},\"title\":\"UUPS Proxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/UUPSProxy.sol\":\"UUPSProxy\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n// Adapted from \\n\\n/**\\n * @authors: [@malatrax]\\n * @reviewers: []\\n * @auditors: []\\n * @bounties: []\\n * @deployments: []\\n */\\npragma solidity 0.8.24;\\n\\n/**\\n * @title UUPS Proxy\\n * @author Simon Malatrait \\n * @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n * @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n * @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n */\\ncontract UUPSProxy {\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n * NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0x7aa5f14ce351299722ac1a1afca9e65e1c795f32ea3e9702b0d5faaf7ca822a0\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561000f575f80fd5b506040516102e53803806102e583398101604081905261002e91610143565b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5580515f14610106575f826001600160a01b031682604051610072919061020b565b5f60405180830381855af49150503d805f81146100aa576040519150601f19603f3d011682016040523d82523d5f602084013e6100af565b606091505b50509050806101045760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050610226565b634e487b7160e01b5f52604160045260245ffd5b5f5b8381101561013b578181015183820152602001610123565b50505f910152565b5f8060408385031215610154575f80fd5b82516001600160a01b038116811461016a575f80fd5b60208401519092506001600160401b0380821115610186575f80fd5b818501915085601f830112610199575f80fd5b8151818111156101ab576101ab61010d565b604051601f8201601f19908116603f011681019083821181831017156101d3576101d361010d565b816040528281528860208487010111156101eb575f80fd5b6101fc836020830160208801610121565b80955050505050509250929050565b5f825161021c818460208701610121565b9190910192915050565b60b3806102325f395ff3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b365f80375f80365f845af43d5f803e8080156079573d5ff35b3d5ffdfea2646970667358221220cef4b52606e73de407a2e27987280e32ca63601b58f184d7d171ca05e6a91f7c64736f6c63430008180033", + "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b365f80375f80365f845af43d5f803e8080156079573d5ff35b3d5ffdfea2646970667358221220cef4b52606e73de407a2e27987280e32ca63601b58f184d7d171ca05e6a91f7c64736f6c63430008180033", + "execute": { + "methodName": "initialize", + "args": [ + "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "0x34B944D42cAcfC8266955D07A80181D2054aa225", + [ + 0, + 10000, + { + "type": "BigNumber", + "hex": "0x016345785d8a0000" + }, + 16 + ] + ] + }, + "implementation": "0x97e30A3A940856A3913437912C746f1aF6ccC76c", + "devdoc": { + "author": "Simon Malatrait ", + "details": "This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.We refer to the Proxiable contract (as per ERC-1822) with `implementation`.", + "kind": "dev", + "methods": { + "constructor": { + "details": "Initializes the upgradeable proxy with an initial implementation specified by `_implementation`. If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor." + } + }, + "stateVariables": { + "IMPLEMENTATION_SLOT": { + "details": "Storage slot with the address of the current implementation. This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is validated in the constructor. NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)" + } + }, + "title": "UUPS Proxy", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler_Implementation.json new file mode 100644 index 000000000..e7b6087ec --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler_Implementation.json @@ -0,0 +1,2221 @@ +{ + "address": "0x97e30A3A940856A3913437912C746f1aF6ccC76c", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AppealFeesNotEnough", + "type": "error" + }, + { + "inputs": [], + "name": "ArbitrationFeesNotEnough", + "type": "error" + }, + { + "inputs": [], + "name": "DisputeNotAppealable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedDelegateCall", + "type": "error" + }, + { + "inputs": [], + "name": "GovernorOnly", + "type": "error" + }, + { + "inputs": [], + "name": "GovernorOrInstructorOnly", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidForkingCourtAsParent", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "NoRulerSet", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "RulerOnly", + "type": "error" + }, + { + "inputs": [], + "name": "RulingAlreadyExecuted", + "type": "error" + }, + { + "inputs": [], + "name": "RulingModeNotSet", + "type": "error" + }, + { + "inputs": [], + "name": "TokenNotAccepted", + "type": "error" + }, + { + "inputs": [], + "name": "TransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [], + "name": "UnsuccessfulCall", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "_accepted", + "type": "bool" + } + ], + "name": "AcceptedFeeToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "AppealDecision", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "AppealPossible", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "indexed": true, + "internalType": "enum KlerosCoreRuler.RulingMode", + "name": "mode", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "overridden", + "type": "bool" + } + ], + "name": "AutoRuled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_courtID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint96", + "name": "_parent", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "CourtCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_roundID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint96", + "name": "_fromCourtID", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "_toCourtID", + "type": "uint96" + } + ], + "name": "CourtJump", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "_courtID", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "CourtModified", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "DisputeCreation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_roundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_pnkAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + } + ], + "name": "LeftoverRewardSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_rateInEth", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "_rateDecimals", + "type": "uint8" + } + ], + "name": "NewCurrencyRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum KlerosCoreRuler.Period", + "name": "_period", + "type": "uint8" + } + ], + "name": "NewPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_oldRuler", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newRuler", + "type": "address" + } + ], + "name": "RulerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum KlerosCoreRuler.RulingMode", + "name": "rulingMode", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "presetRuling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "presetTied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "presetOverridden", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct KlerosCoreRuler.RulerSettings", + "name": "_settings", + "type": "tuple" + } + ], + "name": "RulerSettingsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_roundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_degreeOfCoherency", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "_pnkAmount", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "_feeAmount", + "type": "int256" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + } + ], + "name": "TokenAndETHShift", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "_jump", + "type": "bool" + } + ], + "name": "appeal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_jump", + "type": "bool" + } + ], + "name": "appealCost", + "outputs": [ + { + "internalType": "uint256", + "name": "cost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + }, + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + } + ], + "name": "arbitrationCost", + "outputs": [ + { + "internalType": "uint256", + "name": "cost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "arbitrationCost", + "outputs": [ + { + "internalType": "uint256", + "name": "cost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_accepted", + "type": "bool" + } + ], + "name": "changeAcceptedFeeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "_courtID", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "changeCourtParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "uint64", + "name": "_rateInEth", + "type": "uint64" + }, + { + "internalType": "uint8", + "name": "_rateDecimals", + "type": "uint8" + } + ], + "name": "changeCurrencyRates", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_pinakion", + "type": "address" + } + ], + "name": "changePinakion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "internalType": "address", + "name": "_newRuler", + "type": "address" + } + ], + "name": "changeRuler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_presetRuling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_presetTied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_presetOverridden", + "type": "bool" + } + ], + "name": "changeRulingModeToAutomaticPreset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "changeRulingModeToAutomaticRandom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "_arbitrable", + "type": "address" + } + ], + "name": "changeRulingModeToManual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amountInEth", + "type": "uint256" + } + ], + "name": "convertEthToTokenAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "courts", + "outputs": [ + { + "internalType": "uint96", + "name": "parent", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "hiddenVotes", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "minStake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alpha", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeForJuror", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "jurorsForCourtJump", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "disabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "_parent", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "_hiddenVotes", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_minStake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_alpha", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_feeForJuror", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_jurorsForCourtJump", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "_timesPerPeriod", + "type": "uint256[4]" + } + ], + "name": "createCourt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "createDispute", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + }, + { + "internalType": "contract IERC20", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_feeAmount", + "type": "uint256" + } + ], + "name": "createDispute", + "outputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "currencyRates", + "outputs": [ + { + "internalType": "bool", + "name": "feePaymentAccepted", + "type": "bool" + }, + { + "internalType": "uint64", + "name": "rateInEth", + "type": "uint64" + }, + { + "internalType": "uint8", + "name": "rateDecimals", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "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": "uint96", + "name": "courtID", + "type": "uint96" + }, + { + "internalType": "contract IArbitrableV2", + "name": "arbitrated", + "type": "address" + }, + { + "internalType": "enum KlerosCoreRuler.Period", + "name": "period", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "ruled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_round", + "type": "uint256" + } + ], + "name": "execute", + "outputs": [], + "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": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "overridden", + "type": "bool" + } + ], + "name": "executeRuling", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNextDisputeID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + } + ], + "name": "getNumberOfRounds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + } + ], + "name": "getNumberOfVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_round", + "type": "uint256" + } + ], + "name": "getRoundInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "totalFeesForJurors", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sumFeeRewardPaid", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "feeToken", + "type": "address" + } + ], + "internalType": "struct KlerosCoreRuler.Round", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "_courtID", + "type": "uint96" + } + ], + "name": "getTimesPerPeriod", + "outputs": [ + { + "internalType": "uint256[4]", + "name": "timesPerPeriod", + "type": "uint256[4]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_pinakion", + "type": "address" + }, + { + "internalType": "uint256[4]", + "name": "_courtParameters", + "type": "uint256[4]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pinakion", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IArbitrableV2", + "name": "arbitrable", + "type": "address" + } + ], + "name": "rulers", + "outputs": [ + { + "internalType": "address", + "name": "ruler", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "disputeID", + "type": "uint256" + } + ], + "name": "rulingResults", + "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": "contract IArbitrableV2", + "name": "arbitrable", + "type": "address" + } + ], + "name": "settings", + "outputs": [ + { + "internalType": "enum KlerosCoreRuler.RulingMode", + "name": "rulingMode", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "presetRuling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "presetTied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "presetOverridden", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0x980897f012784c3078669e2fdda6b4a26f637cfb947b775a41d514941a94cd44", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0x97e30A3A940856A3913437912C746f1aF6ccC76c", + "transactionIndex": 1, + "gasUsed": "3342918", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000020000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0954a4104a3be063ea280671e52e5659c5218a334aa322367f9ed19993df3e25", + "transactionHash": "0x980897f012784c3078669e2fdda6b4a26f637cfb947b775a41d514941a94cd44", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 81776138, + "transactionHash": "0x980897f012784c3078669e2fdda6b4a26f637cfb947b775a41d514941a94cd44", + "address": "0x97e30A3A940856A3913437912C746f1aF6ccC76c", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", + "logIndex": 0, + "blockHash": "0x0954a4104a3be063ea280671e52e5659c5218a334aa322367f9ed19993df3e25" + } + ], + "blockNumber": 81776138, + "cumulativeGasUsed": "3342918", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "2c1a31d10a5f76f480d447fbb502d6fc", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AppealFeesNotEnough\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ArbitrationFeesNotEnough\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputeNotAppealable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GovernorOnly\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GovernorOrInstructorOnly\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidForkingCourtAsParent\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoRulerSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RulerOnly\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RulingAlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RulingModeNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsuccessfulCall\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"_accepted\",\"type\":\"bool\"}],\"name\":\"AcceptedFeeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"}],\"name\":\"AppealDecision\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"}],\"name\":\"AppealPossible\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum KlerosCoreRuler.RulingMode\",\"name\":\"mode\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"name\":\"AutoRuled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_courtID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint96\",\"name\":\"_parent\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_hiddenVotes\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minStake\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_alpha\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_feeForJuror\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_jurorsForCourtJump\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[4]\",\"name\":\"_timesPerPeriod\",\"type\":\"uint256[4]\"}],\"name\":\"CourtCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_roundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint96\",\"name\":\"_fromCourtID\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"_toCourtID\",\"type\":\"uint96\"}],\"name\":\"CourtJump\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint96\",\"name\":\"_courtID\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_hiddenVotes\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minStake\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_alpha\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_feeForJuror\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_jurorsForCourtJump\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[4]\",\"name\":\"_timesPerPeriod\",\"type\":\"uint256[4]\"}],\"name\":\"CourtModified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_roundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_pnkAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"LeftoverRewardSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"_rateInEth\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"_rateDecimals\",\"type\":\"uint8\"}],\"name\":\"NewCurrencyRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"enum KlerosCoreRuler.Period\",\"name\":\"_period\",\"type\":\"uint8\"}],\"name\":\"NewPeriod\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_oldRuler\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newRuler\",\"type\":\"address\"}],\"name\":\"RulerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"enum KlerosCoreRuler.RulingMode\",\"name\":\"rulingMode\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"presetRuling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"presetTied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"presetOverridden\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"struct KlerosCoreRuler.RulerSettings\",\"name\":\"_settings\",\"type\":\"tuple\"}],\"name\":\"RulerSettingsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"}],\"name\":\"Ruling\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_roundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_degreeOfCoherency\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"_pnkAmount\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"_feeAmount\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"TokenAndETHShift\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"_jump\",\"type\":\"bool\"}],\"name\":\"appeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_jump\",\"type\":\"bool\"}],\"name\":\"appealCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"cost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"arbitrationCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"cost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"arbitrationCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"cost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_accepted\",\"type\":\"bool\"}],\"name\":\"changeAcceptedFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"_courtID\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"_hiddenVotes\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_minStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_alpha\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_feeForJuror\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_jurorsForCourtJump\",\"type\":\"uint256\"},{\"internalType\":\"uint256[4]\",\"name\":\"_timesPerPeriod\",\"type\":\"uint256[4]\"}],\"name\":\"changeCourtParameters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_rateInEth\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"_rateDecimals\",\"type\":\"uint8\"}],\"name\":\"changeCurrencyRates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_pinakion\",\"type\":\"address\"}],\"name\":\"changePinakion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newRuler\",\"type\":\"address\"}],\"name\":\"changeRuler\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_presetRuling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_presetTied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_presetOverridden\",\"type\":\"bool\"}],\"name\":\"changeRulingModeToAutomaticPreset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"}],\"name\":\"changeRulingModeToAutomaticRandom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IArbitrableV2\",\"name\":\"_arbitrable\",\"type\":\"address\"}],\"name\":\"changeRulingModeToManual\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_toToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amountInEth\",\"type\":\"uint256\"}],\"name\":\"convertEthToTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"courts\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"parent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"hiddenVotes\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"minStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"alpha\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeForJuror\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"jurorsForCourtJump\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"disabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"_parent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"_hiddenVotes\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_minStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_alpha\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_feeForJuror\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_jurorsForCourtJump\",\"type\":\"uint256\"},{\"internalType\":\"uint256[4]\",\"name\":\"_timesPerPeriod\",\"type\":\"uint256[4]\"}],\"name\":\"createCourt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"createDispute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"contract IERC20\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_feeAmount\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"currencyRates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"feePaymentAccepted\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"rateInEth\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"rateDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"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\":\"uint96\",\"name\":\"courtID\",\"type\":\"uint96\"},{\"internalType\":\"contract IArbitrableV2\",\"name\":\"arbitrated\",\"type\":\"address\"},{\"internalType\":\"enum KlerosCoreRuler.Period\",\"name\":\"period\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"ruled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"}],\"name\":\"execute\",\"outputs\":[],\"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\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"name\":\"executeRuling\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNextDisputeID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"}],\"name\":\"getNumberOfRounds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"}],\"name\":\"getNumberOfVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_disputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_round\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"totalFeesForJurors\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"sumFeeRewardPaid\",\"type\":\"uint256\"},{\"internalType\":\"contract IERC20\",\"name\":\"feeToken\",\"type\":\"address\"}],\"internalType\":\"struct KlerosCoreRuler.Round\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"_courtID\",\"type\":\"uint96\"}],\"name\":\"getTimesPerPeriod\",\"outputs\":[{\"internalType\":\"uint256[4]\",\"name\":\"timesPerPeriod\",\"type\":\"uint256[4]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"_pinakion\",\"type\":\"address\"},{\"internalType\":\"uint256[4]\",\"name\":\"_courtParameters\",\"type\":\"uint256[4]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pinakion\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IArbitrableV2\",\"name\":\"arbitrable\",\"type\":\"address\"}],\"name\":\"rulers\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"ruler\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"disputeID\",\"type\":\"uint256\"}],\"name\":\"rulingResults\",\"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\":\"contract IArbitrableV2\",\"name\":\"arbitrable\",\"type\":\"address\"}],\"name\":\"settings\",\"outputs\":[{\"internalType\":\"enum KlerosCoreRuler.RulingMode\",\"name\":\"rulingMode\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"presetRuling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"presetTied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"presetOverridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"AcceptedFeeToken(address,bool)\":{\"details\":\"To be emitted when an ERC20 token is added or removed as a method to pay fees.\",\"params\":{\"_accepted\":\"Whether the token is accepted or not.\",\"_token\":\"The ERC20 token.\"}},\"DisputeCreation(uint256,address)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_arbitrable\":\"The contract which created the dispute.\",\"_disputeID\":\"The identifier of the dispute in the Arbitrator contract.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"NewCurrencyRate(address,uint64,uint8)\":{\"details\":\"To be emitted when the fee for a particular ERC20 token is updated.\",\"params\":{\"_feeToken\":\"The ERC20 token.\",\"_rateDecimals\":\"The new decimals of the fee token rate.\",\"_rateInEth\":\"The new rate of the fee token in ETH.\"}},\"Ruling(address,uint256,uint256)\":{\"details\":\"To be raised when a ruling is given.\",\"params\":{\"_arbitrable\":\"The arbitrable receiving the ruling.\",\"_disputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_ruling\":\"The ruling which was given.\"}},\"Upgraded(address)\":{\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}}},\"kind\":\"dev\",\"methods\":{\"appeal(uint256,uint256,bytes,bool)\":{\"details\":\"Appeals the ruling of a specified dispute.\",\"params\":{\"_disputeID\":\"The ID of the dispute.\",\"_jump\":\"Whether to jump to the parent court or not.\"}},\"appealCost(uint256,bool)\":{\"details\":\"Gets the cost of appealing a specified dispute.\",\"params\":{\"_disputeID\":\"The ID of the dispute.\",\"_jump\":\"Whether to jump to the parent court or not.\"},\"returns\":{\"cost\":\"The appeal cost.\"}},\"arbitrationCost(bytes)\":{\"details\":\"Compute the cost of arbitration denominated in ETH. 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.\",\"params\":{\"_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).\"},\"returns\":{\"cost\":\"The arbitration cost in ETH.\"}},\"arbitrationCost(bytes,address)\":{\"details\":\"Compute the cost of arbitration denominated in `_feeToken`. 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.\",\"params\":{\"_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).\",\"_feeToken\":\"The ERC20 token used to pay fees.\"},\"returns\":{\"cost\":\"The arbitration cost in `_feeToken`.\"}},\"changeAcceptedFeeTokens(address,bool)\":{\"details\":\"Changes the supported fee tokens.\",\"params\":{\"_accepted\":\"Whether the token is supported or not as a method of fee payment.\",\"_feeToken\":\"The fee token.\"}},\"changeCurrencyRates(address,uint64,uint8)\":{\"details\":\"Changes the currency rate of a fee token.\",\"params\":{\"_feeToken\":\"The fee token.\",\"_rateDecimals\":\"The new decimals of the fee token rate.\",\"_rateInEth\":\"The new rate of the fee token in ETH.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"changePinakion(address)\":{\"details\":\"Changes the `pinakion` storage variable.\",\"params\":{\"_pinakion\":\"The new value for the `pinakion` storage variable.\"}},\"constructor\":{\"details\":\"Constructor, initializing the implementation to reduce attack surface.\"},\"createCourt(uint96,bool,uint256,uint256,uint256,uint256,uint256[4])\":{\"details\":\"Creates a court under a specified parent court.\",\"params\":{\"_alpha\":\"The `alpha` property value of the court.\",\"_feeForJuror\":\"The `feeForJuror` property value of the court.\",\"_hiddenVotes\":\"The `hiddenVotes` property value of the court.\",\"_jurorsForCourtJump\":\"The `jurorsForCourtJump` property value of the court.\",\"_minStake\":\"The `minStake` property value of the court.\",\"_parent\":\"The `parent` property value of the court.\",\"_timesPerPeriod\":\"The `timesPerPeriod` property value of the court.\"}},\"createDispute(uint256,bytes)\":{\"details\":\"Create a dispute and pay for the fees in the native currency, typically ETH. Must be called by the arbitrable contract. Must pay at least arbitrationCost(_extraData).\",\"params\":{\"_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).\",\"_numberOfChoices\":\"The number of choices the arbitrator can choose from in this dispute.\"},\"returns\":{\"disputeID\":\"The identifier of the dispute created.\"}},\"createDispute(uint256,bytes,address,uint256)\":{\"details\":\"Create a dispute and pay for the fees in a supported ERC20 token. Must be called by the arbitrable contract. Must pay at least arbitrationCost(_extraData).\",\"params\":{\"_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).\",\"_feeAmount\":\"Amount of the ERC20 token used to pay fees.\",\"_feeToken\":\"The ERC20 token used to pay fees.\",\"_numberOfChoices\":\"The number of choices the arbitrator can choose from in this dispute.\"},\"returns\":{\"disputeID\":\"The identifier of the dispute created.\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_disputeID\":\"The ID of the dispute.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"execute(uint256,uint256)\":{\"details\":\"Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\",\"params\":{\"_disputeID\":\"The ID of the dispute.\",\"_round\":\"The appeal round.\"}},\"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.\"}},\"executeRuling(uint256,uint256,bool,bool)\":{\"details\":\"Executes a specified dispute's ruling.\",\"params\":{\"_disputeID\":\"The ID of the dispute.\"}},\"getNumberOfVotes(uint256)\":{\"details\":\"Gets the number of votes permitted for the specified dispute in the latest round.\",\"params\":{\"_disputeID\":\"The ID of the dispute.\"}},\"initialize(address,address,uint256[4])\":{\"details\":\"Initializer (constructor equivalent for upgradable contracts).\",\"params\":{\"_courtParameters\":\"Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\",\"_governor\":\"The governor's address.\",\"_pinakion\":\"The address of the token contract.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}}},\"title\":\"KlerosCoreRuler Core arbitrator contract for development and testing purposes.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}],\"InvalidImplementation(address)\":[{\"notice\":\"The `implementation` is not UUPS-compliant\"}]},\"events\":{\"Upgraded(address)\":{\"notice\":\"Emitted when the `implementation` has been successfully upgraded.\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/devtools/KlerosCoreRuler.sol\":\"KlerosCoreRuler\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\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 value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"src/arbitration/devtools/KlerosCoreRuler.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"../interfaces/IArbitratorV2.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../../libraries/SafeERC20.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreRuler\\n/// Core arbitrator contract for development and testing purposes.\\ncontract KlerosCoreRuler is IArbitratorV2, UUPSProxiable, Initializable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum RulingMode {\\n uninitialized,\\n manual, // executeRuling() is called manually.\\n automaticRandom, // The ruling is given randomly automatically.\\n automaticPreset // The ruling is given automatically with a preset value.\\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 RulerSettings {\\n RulingMode rulingMode; // The ruling mode of the arbitrator.\\n uint256 presetRuling; // The ruling to give in case of automatic ruling mode.\\n bool presetTied; // Whether the ruling is tied or not.\\n bool presetOverridden; // Whether the ruling is overridden or not.\\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 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 Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees 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 CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n struct RulingResult {\\n uint256 ruling;\\n bool tied;\\n bool overridden;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n IERC20 public pinakion; // The Pinakion token contract.\\n Court[] public courts; // The courts.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n mapping(IArbitrableV2 arbitrable => address ruler) public rulers; // The ruler of each arbitrable contract.\\n mapping(IArbitrableV2 arbitrable => RulerSettings) public settings; // The settings of each arbitrable contract.\\n mapping(uint256 disputeID => RulingResult) public rulingResults; // The ruling results of each dispute.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event 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 );\\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 CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event AutoRuled(\\n IArbitrableV2 indexed _arbitrable,\\n RulingMode indexed mode,\\n uint256 indexed _disputeID,\\n uint256 _ruling,\\n bool tied,\\n bool overridden\\n );\\n event RulerSettingsChanged(IArbitrableV2 indexed _arbitrable, RulerSettings _settings);\\n event RulerChanged(IArbitrableV2 indexed _arbitrable, address indexed _oldRuler, address indexed _newRuler);\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Constructor, initializing the implementation to reduce attack surface.\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n function initialize(\\n address _governor,\\n IERC20 _pinakion,\\n uint256[4] memory _courtParameters\\n ) external reinitializer(1) {\\n governor = _governor;\\n pinakion = _pinakion;\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = false;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = [0, 0, 0, 0];\\n\\n emit CourtCreated(\\n 1,\\n court.parent,\\n court.hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n court.timesPerPeriod\\n );\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /* @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n * @dev Only the governor can perform upgrades (`onlyByGovernor`)\\n */\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\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 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 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 ) external onlyByGovernor {\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\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 // 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 );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n function changeRulingModeToManual(IArbitrableV2 _arbitrable) external {\\n if (rulers[_arbitrable] == address(0)) rulers[_arbitrable] = msg.sender;\\n if (rulers[_arbitrable] != msg.sender) revert RulerOnly();\\n \\n delete settings[_arbitrable];\\n RulerSettings storage arbitratedSettings = settings[_arbitrable];\\n arbitratedSettings.rulingMode = RulingMode.manual;\\n emit RulerSettingsChanged(_arbitrable, arbitratedSettings);\\n }\\n\\n function changeRulingModeToAutomaticRandom(IArbitrableV2 _arbitrable) external {\\n if (rulers[_arbitrable] == address(0)) rulers[_arbitrable] = msg.sender;\\n if (rulers[_arbitrable] != msg.sender) revert RulerOnly();\\n\\n delete settings[_arbitrable];\\n RulerSettings storage arbitratedSettings = settings[_arbitrable];\\n arbitratedSettings.rulingMode = RulingMode.automaticRandom;\\n emit RulerSettingsChanged(_arbitrable, arbitratedSettings);\\n }\\n\\n function changeRulingModeToAutomaticPreset(\\n IArbitrableV2 _arbitrable,\\n uint256 _presetRuling,\\n bool _presetTied,\\n bool _presetOverridden\\n ) external {\\n if (rulers[_arbitrable] == address(0)) rulers[_arbitrable] = msg.sender;\\n if (rulers[_arbitrable] != msg.sender) revert RulerOnly();\\n\\n delete settings[_arbitrable];\\n RulerSettings storage arbitratedSettings = settings[_arbitrable];\\n arbitratedSettings.rulingMode = RulingMode.automaticPreset;\\n arbitratedSettings.presetRuling = _presetRuling;\\n arbitratedSettings.presetTied = _presetTied;\\n arbitratedSettings.presetOverridden = _presetOverridden;\\n emit RulerSettingsChanged(_arbitrable, arbitratedSettings);\\n }\\n\\n function changeRuler(IArbitrableV2 _arbitrable, address _newRuler) external {\\n if (rulers[_arbitrable] != msg.sender) revert RulerOnly();\\n rulers[_arbitrable] = _newRuler;\\n emit RulerChanged(_arbitrable, msg.sender, _newRuler);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal returns (uint256 disputeID) {\\n (uint96 courtID, , ) = _unpackExtraData(_extraData);\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n\\n Round storage round = dispute.rounds.push();\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n _autoRule(disputeID, _numberOfChoices);\\n\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n function _autoRule(uint256 _disputeID, uint256 _numberOfChoices) internal {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 roundID = dispute.rounds.length - 1;\\n RulerSettings storage arbitratedSettings = settings[dispute.arbitrated];\\n if (arbitratedSettings.rulingMode == RulingMode.uninitialized) revert RulingModeNotSet();\\n if (arbitratedSettings.rulingMode == RulingMode.manual) {\\n // NOP\\n } else if (arbitratedSettings.rulingMode == RulingMode.automaticPreset) {\\n emit AutoRuled(\\n dispute.arbitrated,\\n RulingMode.automaticPreset,\\n _disputeID,\\n arbitratedSettings.presetRuling,\\n arbitratedSettings.presetTied,\\n arbitratedSettings.presetOverridden\\n );\\n this.executeRuling(\\n _disputeID,\\n arbitratedSettings.presetRuling,\\n arbitratedSettings.presetTied,\\n arbitratedSettings.presetOverridden\\n );\\n this.execute(_disputeID, roundID);\\n } else if (arbitratedSettings.rulingMode == RulingMode.automaticRandom) {\\n uint256 pseudoRandomNumber = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1)))) %\\n _numberOfChoices; // Not secure but it's just a dev tool for testing, sue me\\n bool tied = pseudoRandomNumber & 4 == 0;\\n bool overridden = pseudoRandomNumber & 2 == 0;\\n emit AutoRuled(\\n dispute.arbitrated,\\n RulingMode.automaticRandom,\\n _disputeID,\\n pseudoRandomNumber,\\n tied,\\n overridden\\n );\\n this.executeRuling(_disputeID, pseudoRandomNumber, tied, overridden);\\n this.execute(_disputeID, roundID);\\n }\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _jump Whether to jump to the parent court or not.\\n function appeal(\\n uint256 _disputeID,\\n uint256 _numberOfChoices,\\n bytes memory /*_extraData*/,\\n bool _jump\\n ) external payable {\\n if (msg.value < appealCost(_disputeID, _jump)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (rulers[dispute.arbitrated] != msg.sender) revert RulerOnly();\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n uint96 newCourtID = dispute.courtID;\\n\\n if (_jump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\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\\n Round storage extraRound = dispute.rounds.push();\\n extraRound.totalFeesForJurors = msg.value;\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n\\n _autoRule(_disputeID, _numberOfChoices);\\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 function execute(uint256 _disputeID, uint256 _round) external {\\n Dispute storage dispute = disputes[_disputeID];\\n address account = rulers[dispute.arbitrated];\\n if (account == address(0)) revert NoRulerSet();\\n\\n // Transfer the fees back to the ruler\\n Round storage round = dispute.rounds[_round];\\n uint256 feeReward = round.totalFeesForJurors;\\n round.sumFeeRewardPaid += feeReward;\\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(account, _disputeID, _round, 1, int256(0), int256(feeReward), round.feeToken);\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID, uint256 _ruling, bool tied, bool overridden) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n if (msg.sender != rulers[dispute.arbitrated] && msg.sender != address(this)) revert RulerOnly();\\n\\n rulingResults[_disputeID] = RulingResult(_ruling, tied, overridden);\\n dispute.ruled = true;\\n dispute.arbitrated.rule(_disputeID, _ruling);\\n\\n emit Ruling(dispute.arbitrated, _disputeID, _ruling);\\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, ) = _unpackExtraData(_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 /// @param _jump Whether to jump to the parent court or not.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID, bool _jump) 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 uint256 nbVotes = round.totalFeesForJurors / court.feeForJuror;\\n if (_jump) {\\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 * ((nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((nbVotes * 2) + 1);\\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 RulingResult storage rulingResult = rulingResults[_disputeID];\\n return (rulingResult.ruling, rulingResult.tied, rulingResult.overridden);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n function getNextDisputeID() external view returns (uint256) {\\n return disputes.length;\\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 Court storage court = courts[dispute.courtID];\\n return dispute.rounds[dispute.rounds.length - 1].totalFeesForJurors / court.feeForJuror;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev 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 _unpackExtraData(\\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) {\\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 GovernorOrInstructorOnly();\\n error RulerOnly();\\n error NoRulerSet();\\n error RulingModeNotSet();\\n error UnsuccessfulCall();\\n error InvalidForkingCourtAsParent();\\n error ArbitrationFeesNotEnough();\\n error TokenNotAccepted();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error RulingAlreadyExecuted();\\n error TransferFailed();\\n}\\n\",\"keccak256\":\"0x32d56f223bd06209e9a90bcafec3af6a6d3da5be41e9cd288d72c67566309e0c\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _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\":\"0xf28c04c5c537d4f2faa02b03c389b6932a8b7061ae6fca91be8db53191c941f6\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked\\n}\\n\",\"keccak256\":\"0x486016fb74cc91439c2ec918e97a79190ab4eed223987d516986fff8eaeecfbf\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n// Adapted from \\n\\n/**\\n * @authors: [@malatrax]\\n * @reviewers: []\\n * @auditors: []\\n * @bounties: []\\n * @deployments: []\\n */\\npragma solidity 0.8.24;\\n\\n/**\\n * @title UUPS Proxiable\\n * @author Simon Malatrait \\n * @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n * The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n *\\n * IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n * This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSProxiable` with a custom implementation of upgrades.\\n *\\n * The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\n */\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /**\\n * Emitted when the `implementation` has been successfully upgraded.\\n * @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n */\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /**\\n * @dev The call is from an unauthorized context.\\n */\\n error UUPSUnauthorizedCallContext();\\n\\n /**\\n * @dev The storage `slot` is unsupported as a UUID.\\n */\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n * NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Storage variable of the proxiable contract address.\\n * It is used to check whether or not the current call is from the proxy.\\n */\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n * @dev Called by {upgradeToAndCall}.\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /**\\n * @dev Upgrade mechanism including access control and UUPS-compliance.\\n * @param newImplementation Address of the new implementation contract.\\n * @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n *\\n * @dev Reverts if the execution is not performed via delegatecall or the execution\\n * context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n /* Check that the execution is being performed through a delegatecall call and that the execution context is\\n a proxy contract with an implementation (as defined in ERC1967) pointing to self. */\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the if statement.\\n */\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5956855046cdda7aa45f44e379ef45323af7266c44c817d1266d8b32d52b0e22\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523060805234801562000014575f80fd5b506200001f62000025565b620000d8565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000755760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d55780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051613232620000ff5f395f81816112df0152818161130801526114fc01526132325ff3fe6080604052600436106101e4575f3560e01c8063564a565d1161010f578063d98493f6116100a8578063e6d49cdf1161006d578063e6d49cdf14610700578063f6506db41461073e578063f7434ea91461075d578063fbf405b01461077c578063fc6f8f161461079b575f80fd5b8063d98493f614610643578063d9ee095f14610662578063db8a173b14610675578063e2373ab314610689578063e4c0aaf4146106e1575f80fd5b8063564a565d146104fd5780636736b70c1461052c578063751accd01461054b5780637934c0be1461056a57806382d022371461058957806386541b24146105a85780638a9bb02a146105c7578063c13517e114610611578063c71f425314610624575f80fd5b80632177470c116101815780632177470c146103db578063379f0a17146103fa5780633cfd11841461042e578063405d51ae1461045a57806343818d661461047957806347cdcc1d146104985780634f1ef286146104b757806352d1902d146104ca5780635601eaea146104de575f80fd5b8062f5822c146101e857806301fcf74d146102095780630219da791461023b57806305d3177d146102ac5780630c340a24146102cb5780630e3993a4146103015780631860592b146103205780631c3db16d1461033f5780631f5a0dd21461037b575b5f80fd5b3480156101f3575f80fd5b50610207610202366004612834565b6107ba565b005b348015610214575f80fd5b50610228610223366004612863565b610806565b6040519081526020015b60405180910390f35b348015610246575f80fd5b50610284610255366004612834565b60046020525f908152604090205460ff808216916001600160401b0361010082041691600160481b9091041683565b6040805193151584526001600160401b03909216602084015260ff1690820152606001610232565b3480156102b7575f80fd5b506102076102c636600461290f565b610958565b3480156102d6575f80fd5b505f546102e9906001600160a01b031681565b6040516001600160a01b039091168152602001610232565b34801561030c575f80fd5b5061020761031b366004612834565b610baf565b34801561032b575f80fd5b5061022861033a366004612954565b610cb6565b34801561034a575f80fd5b5061035e61035936600461297e565b610d0f565b604080519384529115156020840152151590820152606001610232565b348015610386575f80fd5b5061039a61039536600461297e565b610d38565b604080516001600160601b0390981688529515156020880152948601939093526060850191909152608084015260a0830152151560c082015260e001610232565b3480156103e6575f80fd5b506102076103f5366004612995565b610d95565b348015610405575f80fd5b506102e9610414366004612834565b60056020525f90815260409020546001600160a01b031681565b348015610439575f80fd5b5061044d6104483660046129f7565b610f53565b6040516102329190612a32565b348015610465575f80fd5b50610207610474366004612a40565b610fbc565b348015610484575f80fd5b50610207610493366004612834565b611179565b3480156104a3575f80fd5b506102076104b2366004612aa9565b61123a565b6102076104c5366004612b5d565b6112cb565b3480156104d5575f80fd5b506102286114f0565b3480156104e9575f80fd5b506102076104f8366004612ba9565b61154c565b348015610508575f80fd5b5061051c61051736600461297e565b6116b4565b6040516102329493929190612bf1565b348015610537575f80fd5b50610207610546366004612c2e565b611707565b348015610556575f80fd5b50610207610565366004612c63565b611814565b348015610575575f80fd5b50610207610584366004612cb7565b6118b9565b348015610594575f80fd5b506102076105a3366004612ce3565b611936565b3480156105b3575f80fd5b506102076105c2366004612a40565b6119f1565b3480156105d2575f80fd5b506105e66105e1366004612ba9565b611ae2565b604080518251815260208084015190820152918101516001600160a01b031690820152606001610232565b61022861061f366004612d3b565b611b89565b34801561062f575f80fd5b5061022861063e36600461297e565b611bbf565b34801561064e575f80fd5b5061022861065d366004612dac565b611c62565b610207610670366004612df3565b611ca5565b348015610680575f80fd5b50600354610228565b348015610694575f80fd5b506106d16106a3366004612834565b60066020525f908152604090208054600182015460029092015460ff91821692918181169161010090041684565b6040516102329493929190612e56565b3480156106ec575f80fd5b506102076106fb366004612834565b611eed565b34801561070b575f80fd5b5061035e61071a36600461297e565b60076020525f90815260409020805460019091015460ff8082169161010090041683565b348015610749575f80fd5b50610228610758366004612e81565b611f38565b348015610768575f80fd5b50610228610777366004612ee2565b61201a565b348015610787575f80fd5b506001546102e9906001600160a01b031681565b3480156107a6575f80fd5b506102286107b536600461297e565b612062565b5f546001600160a01b031633146107e45760405163c383977560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f806003848154811061081b5761081b612f13565b5f91825260208220600260039092020190810180549193509061084090600190612f3b565b8154811061085057610850612f13565b5f918252602082208454600280546003909402909201945090916001600160601b0390911690811061088457610884612f13565b905f5260205f2090600b020190505f8160040154835f01546108a69190612f62565b905085156109265783546001600160601b03165f19016108cf576001600160ff1b03945061094e565b6108da816002612f75565b6108e5906001612f8c565b82546002805490916001600160601b031690811061090557610905612f13565b905f5260205f2090600b02016004015461091f9190612f75565b945061094e565b610931816002612f75565b61093c906001612f8c565b826004015461094b9190612f75565b94505b5050505092915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805460019190600160401b900460ff16806109a1575080546001600160401b03808416911610155b156109be5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b1781555f80546001600160a01b038088166001600160a01b0319928316178355600180549188169190921617815560028054818452808201909155600b9101027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160601b031916815590604051908082528060200260200182016040528015610a76578160200160208202803683370190505b508051610a8d916001840191602090910190612745565b50805460ff60601b19168155835160028201556020808501516003830155604080860151600480850191909155606080880151600586015582516080810184525f808252948101859052928301849052820192909252610af29160068401919061278e565b50805484516020860151604080880151606089015191516001600160601b038616956001957f0c907a651f88974ed0d9423aacc8b998c40eedf39920e2c3bdae0adcc486a76195610b5895600160601b90930460ff1694919390929060068b0190612f9f565b60405180910390a350805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b038181165f9081526005602052604090205416610bf5576001600160a01b0381165f90815260056020526040902080546001600160a01b031916331790555b6001600160a01b038181165f90815260056020526040902054163314610c2e576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b0381165f908152600660205260408120805460ff191680825560018083019390935560028201805461ffff19169055909190829082805b0217905550816001600160a01b03167ffe3754ab712090753cf700ac7b99f8a5e0f9c69b698312c2cfd0236b852f83f482604051610caa9190612ff9565b60405180910390a25050565b6001600160a01b0382165f9081526004602052604081205461010081046001600160401b031690610cf290600160481b900460ff16600a61311d565b610cfc9084612f75565b610d069190612f62565b90505b92915050565b5f818152600760205260409020805460019091015460ff808216916101009004165b9193909250565b60028181548110610d47575f80fd5b5f9182526020909120600b9091020180546002820154600383015460048401546005850154600a909501546001600160601b038516965060ff600160601b9095048516959394929391921687565b5f60038581548110610da957610da9612f13565b905f5260205f20906003020190508060010160019054906101000a900460ff1615610de75760405163c977f8d360e01b815260040160405180910390fd5b8054600160601b90046001600160a01b039081165f90815260056020526040902054163314801590610e195750333014155b15610e37576040516301627e2760e61b815260040160405180910390fd5b6040805160608101825285815284151560208083019182528515158385019081525f8a815260079092529084902092518355905160019283018054925161ffff1990931691151561ff001990811692909217610100931515840217905591840180549092161790558154905163188d362b60e11b81526004810187905260248101869052600160601b9091046001600160a01b03169063311a6c56906044015f604051808303815f87803b158015610eed575f80fd5b505af1158015610eff573d5f803e3d5ffd5b50508254604051878152889350600160601b9091046001600160a01b031691507f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769060200160405180910390a35050505050565b610f5b6127c1565b6002826001600160601b031681548110610f7757610f77612f13565b5f918252602090912060408051608081019182905292600b029091016006019060049082845b815481526020019060010190808311610f9d5750505050509050919050565b5f546001600160a01b03163314610fe65760405163c383977560e01b815260040160405180910390fd5b6001600160601b03871661100d57604051631ef4f64960e01b815260040160405180910390fd5b600280546001810182555f9182527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace600b82020180546001600160601b0319166001600160601b038b161781559091604051908082528060200260200182016040528015611085578160200160208202803683370190505b50805161109c916001840191602090910190612745565b50805460ff60601b1916600160601b8915150217815560028101879055600381018690556004808201869055600582018590556110df90600683019085906127df565b506002896001600160601b0316815481106110fc576110fc612f13565b5f91825260208083206001600b909302018201805492830181558352909120018290556040516001600160601b038a169083907f0c907a651f88974ed0d9423aacc8b998c40eedf39920e2c3bdae0adcc486a76190611166908c908c908c908c908c908c9061312b565b60405180910390a3505050505050505050565b6001600160a01b038181165f90815260056020526040902054166111bf576001600160a01b0381165f90815260056020526040902080546001600160a01b031916331790555b6001600160a01b038181165f908152600560205260409020541633146111f8576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b0381165f908152600660205260408120805460ff19168082556001808301939093556002808301805461ffff19169055919283919083610c6c565b6001600160a01b038281165f90815260056020526040902054163314611273576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b038281165f8181526005602052604080822080546001600160a01b0319169486169485179055513392917ff512a4524e61d860055823df1f2a5f33de24eb2a03dc3de501015ad501d4e36f91a45050565b6112d48261208f565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061135157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113455f805160206131dd8339815191525490565b6001600160a01b031614155b1561136f5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156113c9575060408051601f3d908101601f191682019092526113c69181019061315d565b60015b6113f657604051630c76093760e01b81526001600160a01b03831660048201526024015b60405180910390fd5b5f805160206131dd833981519152811461142657604051632a87526960e21b8152600481018290526024016113ed565b5f805160206131dd8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28151156114eb575f836001600160a01b03168360405161148a9190613174565b5f60405180830381855af49150503d805f81146114c2576040519150601f19603f3d011682016040523d82523d5f602084013e6114c7565b606091505b50509050806114e9576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b5f306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461153a5760405163703e46dd60e11b815260040160405180910390fd5b505f805160206131dd83398151915290565b5f6003838154811061156057611560612f13565b5f9182526020808320600390920290910180546001600160a01b03600160601b90910481168452600590925260409092205491925016806115b45760405163f4612fe560e01b815260040160405180910390fd5b5f8260020184815481106115ca576115ca612f13565b905f5260205f20906003020190505f815f0154905080826001015f8282546115f29190612f8c565b909155505060028201546001600160a01b0316611633576040516001600160a01b0384169082156108fc029083905f818181858888f193505050505061164e565b600282015461164c906001600160a01b031684836120bc565b505b600282015460408051600181525f60208201529081018390526001600160a01b03918216606082015286918891908616907f8975b837fe0d18616c65abb8b843726a32b552ee4feca009944fa658bbb282e79060800160405180910390a4505050505050565b600381815481106116c3575f80fd5b5f918252602090912060039091020180546001909101546001600160601b0382169250600160601b9091046001600160a01b03169060ff8082169161010090041684565b6001600160a01b038481165f908152600560205260409020541661174d576001600160a01b0384165f90815260056020526040902080546001600160a01b031916331790555b6001600160a01b038481165f90815260056020526040902054163314611786576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b0384165f8181526006602052604090819020805460028201805460ff1990921660031783556001830188905561ffff1990911686151561ff001916176101008615150217905590519091907ffe3754ab712090753cf700ac7b99f8a5e0f9c69b698312c2cfd0236b852f83f490611805908490612ff9565b60405180910390a25050505050565b5f546001600160a01b0316331461183e5760405163c383977560e01b815260040160405180910390fd5b5f836001600160a01b031683836040516118589190613174565b5f6040518083038185875af1925050503d805f8114611892576040519150601f19603f3d011682016040523d82523d5f602084013e611897565b606091505b50509050806114e9576040516322092f2f60e11b815260040160405180910390fd5b5f546001600160a01b031633146118e35760405163c383977560e01b815260040160405180910390fd5b6001600160a01b0382165f81815260046020526040808220805460ff191685151590811790915590519092917f541615e167511d757a7067a700eb54431b256bb458dfdce0ac58bf2ed0aefd4491a35050565b5f546001600160a01b031633146119605760405163c383977560e01b815260040160405180910390fd5b6001600160a01b0383165f81815260046020908152604091829020805469ffffffffffffffffff0019166101006001600160401b03881690810260ff60481b191691909117600160481b60ff8816908102919091179092558351908152918201527fe6996b7f03e9bd02228b99d3d946932e3197f505f60542c4cfbc919441d8a4e6910160405180910390a2505050565b5f546001600160a01b03163314611a1b5760405163c383977560e01b815260040160405180910390fd5b5f6002886001600160601b031681548110611a3857611a38612f13565b5f9182526020909120600b9091020160028101879055805460ff60601b1916600160601b8915150217815560038101869055600480820186905560058201859055909150611a8c90600683019084906127df565b50876001600160601b03167f709b1f5fda58af9a4f52dacd1ec404840a8148455700cce155a2bd8cf127ef1a888888888888604051611ad09695949392919061312b565b60405180910390a25050505050505050565b611b0c60405180606001604052805f81526020015f81526020015f6001600160a01b031681525090565b60038381548110611b1f57611b1f612f13565b905f5260205f2090600302016002018281548110611b3f57611b3f612f13565b5f918252602091829020604080516060810182526003909302909101805483526001810154938301939093526002909201546001600160a01b031691810191909152905092915050565b5f611b938261201a565b341015611bb357604051630e3360f160e21b815260040160405180910390fd5b610d0683835f34612180565b5f8060038381548110611bd457611bd4612f13565b5f91825260208220600390910201805460028054929450916001600160601b03909116908110611c0657611c06612f13565b905f5260205f2090600b0201905080600401548260020160018460020180549050611c319190612f3b565b81548110611c4157611c41612f13565b905f5260205f2090600302015f0154611c5a9190612f62565b949350505050565b5f611c5a8261033a86868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061201a92505050565b611caf8482610806565b341015611ccf57604051633191f8f160e01b815260040160405180910390fd5b5f60038581548110611ce357611ce3612f13565b5f918252602080832060039092029091018054600160601b90046001600160a01b0390811684526005909252604090922054919250163314611d38576040516301627e2760e61b815260040160405180910390fd5b6003600182015460ff166004811115611d5357611d53612bc9565b14611d71576040516337cdefcb60e21b815260040160405180910390fd5b80546001600160601b03168215611e22576002816001600160601b031681548110611d9e57611d9e612f13565b5f9182526020909120600b909102015482546001600160601b039182169250168114611e2257815460028301546001600160601b0390911690611de390600190612f3b565b6040516001600160601b038416815288907f736e3f52761298c8c0823e1ebf482ed3c5ecb304f743d2d91a7c006e8e8d7a1f9060200160405180910390a45b81546001600160601b0319166001600160601b0382161782556001808301805460ff1916905560028301805491820181555f90815260208120346003909302019182558354604051600160601b9091046001600160a01b03169189917f9c9b64db9e130f48381bf697abf638e73117dbfbfd7a4484f2da3ba188f4187d9190a3867f4e6f5cf43b95303e86aee81683df63992061723a829ee012db21dad388756b915f604051611ed291906131a0565b60405180910390a2611ee48787612272565b50505050505050565b5f546001600160a01b03163314611f175760405163c383977560e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382165f9081526004602052604081205460ff16611f705760405163e51cf7bf60e01b815260040160405180910390fd5b611f7b858585611c62565b821015611f9b57604051630e3360f160e21b815260040160405180910390fd5b611fb06001600160a01b0384163330856125fc565b611fcd576040516312171d8360e31b815260040160405180910390fd5b6120108686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508892508791506121809050565b9695505050505050565b5f805f612026846126d3565b5091509150806002836001600160601b03168154811061204857612048612f13565b905f5260205f2090600b020160040154611c5a9190612f75565b5f6003828154811061207657612076612f13565b5f91825260209091206002600390920201015492915050565b5f546001600160a01b031633146120b95760405163c383977560e01b815260040160405180910390fd5b50565b6040516001600160a01b038381166024830152604482018390525f91829182919087169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b179052516121189190613174565b5f604051808303815f865af19150503d805f8114612151576040519150601f19603f3d011682016040523d82523d5f602084013e612156565b606091505b509150915081801561201057508051158061201057508080602001905181019061201091906131ae565b5f8061218b856126d3565b505060038054600180820183556001600160601b03841633600160601b02177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b8385029081019182557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d01805492830181555f9081526020902091909302018681556002810180546001600160a01b0319166001600160a01b038a161790559094509192509061223b8489612272565b604051339085907f141dfc18aa6a56fc816f44f0e9e2f1ebc92b15ab167770e17db5b084c10ed995905f90a3505050949350505050565b5f6003838154811061228657612286612f13565b905f5260205f20906003020190505f600182600201805490506122a99190612f3b565b8254600160601b90046001600160a01b03165f908152600660205260408120919250815460ff1660038111156122e1576122e1612bc9565b036122ff5760405163d8f2465160e01b815260040160405180910390fd5b6001815460ff16600381111561231757612317612bc9565b146125f5576003815460ff16600381111561233457612334612bc9565b03612479578460038454600184015460028501546040805192835260ff80831615156020850152610100909204909116151590820152600160601b9091046001600160a01b0316907f45c27c7ea7135714f09b069efa7497d57c38017d4e919c5535ba31dbd5b597e69060600160405180910390a46001810154600282015460405163085dd1c360e21b815260048101889052602481019290925260ff8082161515604484015261010090910416151560648201523090632177470c906084015f604051808303815f87803b15801561240b575f80fd5b505af115801561241d573d5f803e3d5ffd5b5050604051632b00f57560e11b81526004810188905260248101859052309250635601eaea91506044015f604051808303815f87803b15801561245e575f80fd5b505af1158015612470573d5f803e3d5ffd5b505050506125f5565b6002815460ff16600381111561249157612491612bc9565b036125f5575f846124a3600143612f3b565b604080519140602083015201604051602081830303815290604052805190602001205f1c6124d191906131c9565b90506004811615600280831615908890875460408051878152861515602082015285151591810191909152600160601b9091046001600160a01b0316907f45c27c7ea7135714f09b069efa7497d57c38017d4e919c5535ba31dbd5b597e69060600160405180910390a460405163085dd1c360e21b81526004810189905260248101849052821515604482015281151560648201523090632177470c906084015f604051808303815f87803b158015612588575f80fd5b505af115801561259a573d5f803e3d5ffd5b5050604051632b00f57560e11b8152600481018b905260248101889052309250635601eaea91506044015f604051808303815f87803b1580156125db575f80fd5b505af11580156125ed573d5f803e3d5ffd5b505050505050505b5050505050565b6040516001600160a01b0384811660248301528381166044830152606482018390525f91829182919088169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b179052516126609190613174565b5f604051808303815f865af19150503d805f8114612699576040519150601f19603f3d011682016040523d82523d5f602084013e61269e565b606091505b50915091508180156126c85750805115806126c85750808060200190518101906126c891906131ae565b979650505050505050565b5f805f6040845110612736575050506020810151604082015160608301516001600160601b038316158061271257506002546001600160601b03841610155b1561271c57600192505b815f0361272857600391505b80612731575060015b610d31565b50600193600393508492509050565b828054828255905f5260205f2090810192821561277e579160200282015b8281111561277e578251825591602001919060010190612763565b5061278a92915061280c565b5090565b826004810192821561277e579160200282015b8281111561277e578251829060ff169055916020019190600101906127a1565b60405180608001604052806004906020820280368337509192915050565b826004810192821561277e579160200282018281111561277e578251825591602001919060010190612763565b5b8082111561278a575f815560010161280d565b6001600160a01b03811681146120b9575f80fd5b5f60208284031215612844575f80fd5b813561284f81612820565b9392505050565b80151581146120b9575f80fd5b5f8060408385031215612874575f80fd5b82359150602083013561288681612856565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126128b4575f80fd5b604051608081018181106001600160401b03821117156128d6576128d6612891565b6040528060808401858111156128ea575f80fd5b845b818110156129045780358352602092830192016128ec565b509195945050505050565b5f805f60c08486031215612921575f80fd5b833561292c81612820565b9250602084013561293c81612820565b915061294b85604086016128a5565b90509250925092565b5f8060408385031215612965575f80fd5b823561297081612820565b946020939093013593505050565b5f6020828403121561298e575f80fd5b5035919050565b5f805f80608085870312156129a8575f80fd5b843593506020850135925060408501356129c181612856565b915060608501356129d181612856565b939692955090935050565b80356001600160601b03811681146129f2575f80fd5b919050565b5f60208284031215612a07575f80fd5b610d06826129dc565b805f5b60048110156114e9578151845260209384019390910190600101612a13565b60808101610d098284612a10565b5f805f805f805f610140888a031215612a57575f80fd5b612a60886129dc565b96506020880135612a7081612856565b955060408801359450606088013593506080880135925060a08801359150612a9b8960c08a016128a5565b905092959891949750929550565b5f8060408385031215612aba575f80fd5b8235612ac581612820565b9150602083013561288681612820565b5f82601f830112612ae4575f80fd5b81356001600160401b0380821115612afe57612afe612891565b604051601f8301601f19908116603f01168101908282118183101715612b2657612b26612891565b81604052838152866020858801011115612b3e575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215612b6e575f80fd5b8235612b7981612820565b915060208301356001600160401b03811115612b93575f80fd5b612b9f85828601612ad5565b9150509250929050565b5f8060408385031215612bba575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52602160045260245ffd5b60058110612bed57612bed612bc9565b9052565b6001600160601b03851681526001600160a01b038416602082015260808101612c1d6040830185612bdd565b821515606083015295945050505050565b5f805f8060808587031215612c41575f80fd5b8435612c4c81612820565b93506020850135925060408501356129c181612856565b5f805f60608486031215612c75575f80fd5b8335612c8081612820565b92506020840135915060408401356001600160401b03811115612ca1575f80fd5b612cad86828701612ad5565b9150509250925092565b5f8060408385031215612cc8575f80fd5b8235612cd381612820565b9150602083013561288681612856565b5f805f60608486031215612cf5575f80fd5b8335612d0081612820565b925060208401356001600160401b0381168114612d1b575f80fd5b9150604084013560ff81168114612d30575f80fd5b809150509250925092565b5f8060408385031215612d4c575f80fd5b8235915060208301356001600160401b03811115612b93575f80fd5b5f8083601f840112612d78575f80fd5b5081356001600160401b03811115612d8e575f80fd5b602083019150836020828501011115612da5575f80fd5b9250929050565b5f805f60408486031215612dbe575f80fd5b83356001600160401b03811115612dd3575f80fd5b612ddf86828701612d68565b9094509250506020840135612d3081612820565b5f805f8060808587031215612e06575f80fd5b843593506020850135925060408501356001600160401b03811115612e29575f80fd5b612e3587828801612ad5565b92505060608501356129d181612856565b60048110612bed57612bed612bc9565b60808101612e648287612e46565b602082019490945291151560408301521515606090910152919050565b5f805f805f60808688031215612e95575f80fd5b8535945060208601356001600160401b03811115612eb1575f80fd5b612ebd88828901612d68565b9095509350506040860135612ed181612820565b949793965091946060013592915050565b5f60208284031215612ef2575f80fd5b81356001600160401b03811115612f07575f80fd5b611c5a84828501612ad5565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d0957610d09612f27565b634e487b7160e01b5f52601260045260245ffd5b5f82612f7057612f70612f4e565b500490565b8082028115828204841417610d0957610d09612f27565b80820180821115610d0957610d09612f27565b5f610120820190508715158252602087602084015286604084015285606084015284608084015260a08301845f5b6004811015612fea57815483529183019160019182019101612fcd565b50505050979650505050505050565b5f60808201905061300e8260ff855416612e46565b60018301546020830152600283015460ff81161515604084015260ff8160081c16151560608401525092915050565b600181815b8085111561307757815f190482111561305d5761305d612f27565b8085161561306a57918102915b93841c9390800290613042565b509250929050565b5f8261308d57506001610d09565b8161309957505f610d09565b81600181146130af57600281146130b9576130d5565b6001915050610d09565b60ff8411156130ca576130ca612f27565b50506001821b610d09565b5060208310610133831016604e8410600b84101617156130f8575081810a610d09565b613102838361303d565b805f190482111561311557613115612f27565b029392505050565b5f610d0660ff84168361307f565b5f6101208201905087151582528660208301528560408301528460608301528360808301526126c860a0830184612a10565b5f6020828403121561316d575f80fd5b5051919050565b5f82515f5b818110156131935760208186018101518583015201613179565b505f920191825250919050565b60208101610d098284612bdd565b5f602082840312156131be575f80fd5b815161284f81612856565b5f826131d7576131d7612f4e565b50069056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220f2e22a0dce5ce1f5dee73c7f609484912562e77d9ae9b2964b5eeed771279c2464736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106101e4575f3560e01c8063564a565d1161010f578063d98493f6116100a8578063e6d49cdf1161006d578063e6d49cdf14610700578063f6506db41461073e578063f7434ea91461075d578063fbf405b01461077c578063fc6f8f161461079b575f80fd5b8063d98493f614610643578063d9ee095f14610662578063db8a173b14610675578063e2373ab314610689578063e4c0aaf4146106e1575f80fd5b8063564a565d146104fd5780636736b70c1461052c578063751accd01461054b5780637934c0be1461056a57806382d022371461058957806386541b24146105a85780638a9bb02a146105c7578063c13517e114610611578063c71f425314610624575f80fd5b80632177470c116101815780632177470c146103db578063379f0a17146103fa5780633cfd11841461042e578063405d51ae1461045a57806343818d661461047957806347cdcc1d146104985780634f1ef286146104b757806352d1902d146104ca5780635601eaea146104de575f80fd5b8062f5822c146101e857806301fcf74d146102095780630219da791461023b57806305d3177d146102ac5780630c340a24146102cb5780630e3993a4146103015780631860592b146103205780631c3db16d1461033f5780631f5a0dd21461037b575b5f80fd5b3480156101f3575f80fd5b50610207610202366004612834565b6107ba565b005b348015610214575f80fd5b50610228610223366004612863565b610806565b6040519081526020015b60405180910390f35b348015610246575f80fd5b50610284610255366004612834565b60046020525f908152604090205460ff808216916001600160401b0361010082041691600160481b9091041683565b6040805193151584526001600160401b03909216602084015260ff1690820152606001610232565b3480156102b7575f80fd5b506102076102c636600461290f565b610958565b3480156102d6575f80fd5b505f546102e9906001600160a01b031681565b6040516001600160a01b039091168152602001610232565b34801561030c575f80fd5b5061020761031b366004612834565b610baf565b34801561032b575f80fd5b5061022861033a366004612954565b610cb6565b34801561034a575f80fd5b5061035e61035936600461297e565b610d0f565b604080519384529115156020840152151590820152606001610232565b348015610386575f80fd5b5061039a61039536600461297e565b610d38565b604080516001600160601b0390981688529515156020880152948601939093526060850191909152608084015260a0830152151560c082015260e001610232565b3480156103e6575f80fd5b506102076103f5366004612995565b610d95565b348015610405575f80fd5b506102e9610414366004612834565b60056020525f90815260409020546001600160a01b031681565b348015610439575f80fd5b5061044d6104483660046129f7565b610f53565b6040516102329190612a32565b348015610465575f80fd5b50610207610474366004612a40565b610fbc565b348015610484575f80fd5b50610207610493366004612834565b611179565b3480156104a3575f80fd5b506102076104b2366004612aa9565b61123a565b6102076104c5366004612b5d565b6112cb565b3480156104d5575f80fd5b506102286114f0565b3480156104e9575f80fd5b506102076104f8366004612ba9565b61154c565b348015610508575f80fd5b5061051c61051736600461297e565b6116b4565b6040516102329493929190612bf1565b348015610537575f80fd5b50610207610546366004612c2e565b611707565b348015610556575f80fd5b50610207610565366004612c63565b611814565b348015610575575f80fd5b50610207610584366004612cb7565b6118b9565b348015610594575f80fd5b506102076105a3366004612ce3565b611936565b3480156105b3575f80fd5b506102076105c2366004612a40565b6119f1565b3480156105d2575f80fd5b506105e66105e1366004612ba9565b611ae2565b604080518251815260208084015190820152918101516001600160a01b031690820152606001610232565b61022861061f366004612d3b565b611b89565b34801561062f575f80fd5b5061022861063e36600461297e565b611bbf565b34801561064e575f80fd5b5061022861065d366004612dac565b611c62565b610207610670366004612df3565b611ca5565b348015610680575f80fd5b50600354610228565b348015610694575f80fd5b506106d16106a3366004612834565b60066020525f908152604090208054600182015460029092015460ff91821692918181169161010090041684565b6040516102329493929190612e56565b3480156106ec575f80fd5b506102076106fb366004612834565b611eed565b34801561070b575f80fd5b5061035e61071a36600461297e565b60076020525f90815260409020805460019091015460ff8082169161010090041683565b348015610749575f80fd5b50610228610758366004612e81565b611f38565b348015610768575f80fd5b50610228610777366004612ee2565b61201a565b348015610787575f80fd5b506001546102e9906001600160a01b031681565b3480156107a6575f80fd5b506102286107b536600461297e565b612062565b5f546001600160a01b031633146107e45760405163c383977560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f806003848154811061081b5761081b612f13565b5f91825260208220600260039092020190810180549193509061084090600190612f3b565b8154811061085057610850612f13565b5f918252602082208454600280546003909402909201945090916001600160601b0390911690811061088457610884612f13565b905f5260205f2090600b020190505f8160040154835f01546108a69190612f62565b905085156109265783546001600160601b03165f19016108cf576001600160ff1b03945061094e565b6108da816002612f75565b6108e5906001612f8c565b82546002805490916001600160601b031690811061090557610905612f13565b905f5260205f2090600b02016004015461091f9190612f75565b945061094e565b610931816002612f75565b61093c906001612f8c565b826004015461094b9190612f75565b94505b5050505092915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805460019190600160401b900460ff16806109a1575080546001600160401b03808416911610155b156109be5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b1781555f80546001600160a01b038088166001600160a01b0319928316178355600180549188169190921617815560028054818452808201909155600b9101027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160601b031916815590604051908082528060200260200182016040528015610a76578160200160208202803683370190505b508051610a8d916001840191602090910190612745565b50805460ff60601b19168155835160028201556020808501516003830155604080860151600480850191909155606080880151600586015582516080810184525f808252948101859052928301849052820192909252610af29160068401919061278e565b50805484516020860151604080880151606089015191516001600160601b038616956001957f0c907a651f88974ed0d9423aacc8b998c40eedf39920e2c3bdae0adcc486a76195610b5895600160601b90930460ff1694919390929060068b0190612f9f565b60405180910390a350805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b038181165f9081526005602052604090205416610bf5576001600160a01b0381165f90815260056020526040902080546001600160a01b031916331790555b6001600160a01b038181165f90815260056020526040902054163314610c2e576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b0381165f908152600660205260408120805460ff191680825560018083019390935560028201805461ffff19169055909190829082805b0217905550816001600160a01b03167ffe3754ab712090753cf700ac7b99f8a5e0f9c69b698312c2cfd0236b852f83f482604051610caa9190612ff9565b60405180910390a25050565b6001600160a01b0382165f9081526004602052604081205461010081046001600160401b031690610cf290600160481b900460ff16600a61311d565b610cfc9084612f75565b610d069190612f62565b90505b92915050565b5f818152600760205260409020805460019091015460ff808216916101009004165b9193909250565b60028181548110610d47575f80fd5b5f9182526020909120600b9091020180546002820154600383015460048401546005850154600a909501546001600160601b038516965060ff600160601b9095048516959394929391921687565b5f60038581548110610da957610da9612f13565b905f5260205f20906003020190508060010160019054906101000a900460ff1615610de75760405163c977f8d360e01b815260040160405180910390fd5b8054600160601b90046001600160a01b039081165f90815260056020526040902054163314801590610e195750333014155b15610e37576040516301627e2760e61b815260040160405180910390fd5b6040805160608101825285815284151560208083019182528515158385019081525f8a815260079092529084902092518355905160019283018054925161ffff1990931691151561ff001990811692909217610100931515840217905591840180549092161790558154905163188d362b60e11b81526004810187905260248101869052600160601b9091046001600160a01b03169063311a6c56906044015f604051808303815f87803b158015610eed575f80fd5b505af1158015610eff573d5f803e3d5ffd5b50508254604051878152889350600160601b9091046001600160a01b031691507f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769060200160405180910390a35050505050565b610f5b6127c1565b6002826001600160601b031681548110610f7757610f77612f13565b5f918252602090912060408051608081019182905292600b029091016006019060049082845b815481526020019060010190808311610f9d5750505050509050919050565b5f546001600160a01b03163314610fe65760405163c383977560e01b815260040160405180910390fd5b6001600160601b03871661100d57604051631ef4f64960e01b815260040160405180910390fd5b600280546001810182555f9182527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace600b82020180546001600160601b0319166001600160601b038b161781559091604051908082528060200260200182016040528015611085578160200160208202803683370190505b50805161109c916001840191602090910190612745565b50805460ff60601b1916600160601b8915150217815560028101879055600381018690556004808201869055600582018590556110df90600683019085906127df565b506002896001600160601b0316815481106110fc576110fc612f13565b5f91825260208083206001600b909302018201805492830181558352909120018290556040516001600160601b038a169083907f0c907a651f88974ed0d9423aacc8b998c40eedf39920e2c3bdae0adcc486a76190611166908c908c908c908c908c908c9061312b565b60405180910390a3505050505050505050565b6001600160a01b038181165f90815260056020526040902054166111bf576001600160a01b0381165f90815260056020526040902080546001600160a01b031916331790555b6001600160a01b038181165f908152600560205260409020541633146111f8576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b0381165f908152600660205260408120805460ff19168082556001808301939093556002808301805461ffff19169055919283919083610c6c565b6001600160a01b038281165f90815260056020526040902054163314611273576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b038281165f8181526005602052604080822080546001600160a01b0319169486169485179055513392917ff512a4524e61d860055823df1f2a5f33de24eb2a03dc3de501015ad501d4e36f91a45050565b6112d48261208f565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061135157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113455f805160206131dd8339815191525490565b6001600160a01b031614155b1561136f5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156113c9575060408051601f3d908101601f191682019092526113c69181019061315d565b60015b6113f657604051630c76093760e01b81526001600160a01b03831660048201526024015b60405180910390fd5b5f805160206131dd833981519152811461142657604051632a87526960e21b8152600481018290526024016113ed565b5f805160206131dd8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28151156114eb575f836001600160a01b03168360405161148a9190613174565b5f60405180830381855af49150503d805f81146114c2576040519150601f19603f3d011682016040523d82523d5f602084013e6114c7565b606091505b50509050806114e9576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b5f306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461153a5760405163703e46dd60e11b815260040160405180910390fd5b505f805160206131dd83398151915290565b5f6003838154811061156057611560612f13565b5f9182526020808320600390920290910180546001600160a01b03600160601b90910481168452600590925260409092205491925016806115b45760405163f4612fe560e01b815260040160405180910390fd5b5f8260020184815481106115ca576115ca612f13565b905f5260205f20906003020190505f815f0154905080826001015f8282546115f29190612f8c565b909155505060028201546001600160a01b0316611633576040516001600160a01b0384169082156108fc029083905f818181858888f193505050505061164e565b600282015461164c906001600160a01b031684836120bc565b505b600282015460408051600181525f60208201529081018390526001600160a01b03918216606082015286918891908616907f8975b837fe0d18616c65abb8b843726a32b552ee4feca009944fa658bbb282e79060800160405180910390a4505050505050565b600381815481106116c3575f80fd5b5f918252602090912060039091020180546001909101546001600160601b0382169250600160601b9091046001600160a01b03169060ff8082169161010090041684565b6001600160a01b038481165f908152600560205260409020541661174d576001600160a01b0384165f90815260056020526040902080546001600160a01b031916331790555b6001600160a01b038481165f90815260056020526040902054163314611786576040516301627e2760e61b815260040160405180910390fd5b6001600160a01b0384165f8181526006602052604090819020805460028201805460ff1990921660031783556001830188905561ffff1990911686151561ff001916176101008615150217905590519091907ffe3754ab712090753cf700ac7b99f8a5e0f9c69b698312c2cfd0236b852f83f490611805908490612ff9565b60405180910390a25050505050565b5f546001600160a01b0316331461183e5760405163c383977560e01b815260040160405180910390fd5b5f836001600160a01b031683836040516118589190613174565b5f6040518083038185875af1925050503d805f8114611892576040519150601f19603f3d011682016040523d82523d5f602084013e611897565b606091505b50509050806114e9576040516322092f2f60e11b815260040160405180910390fd5b5f546001600160a01b031633146118e35760405163c383977560e01b815260040160405180910390fd5b6001600160a01b0382165f81815260046020526040808220805460ff191685151590811790915590519092917f541615e167511d757a7067a700eb54431b256bb458dfdce0ac58bf2ed0aefd4491a35050565b5f546001600160a01b031633146119605760405163c383977560e01b815260040160405180910390fd5b6001600160a01b0383165f81815260046020908152604091829020805469ffffffffffffffffff0019166101006001600160401b03881690810260ff60481b191691909117600160481b60ff8816908102919091179092558351908152918201527fe6996b7f03e9bd02228b99d3d946932e3197f505f60542c4cfbc919441d8a4e6910160405180910390a2505050565b5f546001600160a01b03163314611a1b5760405163c383977560e01b815260040160405180910390fd5b5f6002886001600160601b031681548110611a3857611a38612f13565b5f9182526020909120600b9091020160028101879055805460ff60601b1916600160601b8915150217815560038101869055600480820186905560058201859055909150611a8c90600683019084906127df565b50876001600160601b03167f709b1f5fda58af9a4f52dacd1ec404840a8148455700cce155a2bd8cf127ef1a888888888888604051611ad09695949392919061312b565b60405180910390a25050505050505050565b611b0c60405180606001604052805f81526020015f81526020015f6001600160a01b031681525090565b60038381548110611b1f57611b1f612f13565b905f5260205f2090600302016002018281548110611b3f57611b3f612f13565b5f918252602091829020604080516060810182526003909302909101805483526001810154938301939093526002909201546001600160a01b031691810191909152905092915050565b5f611b938261201a565b341015611bb357604051630e3360f160e21b815260040160405180910390fd5b610d0683835f34612180565b5f8060038381548110611bd457611bd4612f13565b5f91825260208220600390910201805460028054929450916001600160601b03909116908110611c0657611c06612f13565b905f5260205f2090600b0201905080600401548260020160018460020180549050611c319190612f3b565b81548110611c4157611c41612f13565b905f5260205f2090600302015f0154611c5a9190612f62565b949350505050565b5f611c5a8261033a86868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061201a92505050565b611caf8482610806565b341015611ccf57604051633191f8f160e01b815260040160405180910390fd5b5f60038581548110611ce357611ce3612f13565b5f918252602080832060039092029091018054600160601b90046001600160a01b0390811684526005909252604090922054919250163314611d38576040516301627e2760e61b815260040160405180910390fd5b6003600182015460ff166004811115611d5357611d53612bc9565b14611d71576040516337cdefcb60e21b815260040160405180910390fd5b80546001600160601b03168215611e22576002816001600160601b031681548110611d9e57611d9e612f13565b5f9182526020909120600b909102015482546001600160601b039182169250168114611e2257815460028301546001600160601b0390911690611de390600190612f3b565b6040516001600160601b038416815288907f736e3f52761298c8c0823e1ebf482ed3c5ecb304f743d2d91a7c006e8e8d7a1f9060200160405180910390a45b81546001600160601b0319166001600160601b0382161782556001808301805460ff1916905560028301805491820181555f90815260208120346003909302019182558354604051600160601b9091046001600160a01b03169189917f9c9b64db9e130f48381bf697abf638e73117dbfbfd7a4484f2da3ba188f4187d9190a3867f4e6f5cf43b95303e86aee81683df63992061723a829ee012db21dad388756b915f604051611ed291906131a0565b60405180910390a2611ee48787612272565b50505050505050565b5f546001600160a01b03163314611f175760405163c383977560e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382165f9081526004602052604081205460ff16611f705760405163e51cf7bf60e01b815260040160405180910390fd5b611f7b858585611c62565b821015611f9b57604051630e3360f160e21b815260040160405180910390fd5b611fb06001600160a01b0384163330856125fc565b611fcd576040516312171d8360e31b815260040160405180910390fd5b6120108686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508892508791506121809050565b9695505050505050565b5f805f612026846126d3565b5091509150806002836001600160601b03168154811061204857612048612f13565b905f5260205f2090600b020160040154611c5a9190612f75565b5f6003828154811061207657612076612f13565b5f91825260209091206002600390920201015492915050565b5f546001600160a01b031633146120b95760405163c383977560e01b815260040160405180910390fd5b50565b6040516001600160a01b038381166024830152604482018390525f91829182919087169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b179052516121189190613174565b5f604051808303815f865af19150503d805f8114612151576040519150601f19603f3d011682016040523d82523d5f602084013e612156565b606091505b509150915081801561201057508051158061201057508080602001905181019061201091906131ae565b5f8061218b856126d3565b505060038054600180820183556001600160601b03841633600160601b02177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b8385029081019182557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d01805492830181555f9081526020902091909302018681556002810180546001600160a01b0319166001600160a01b038a161790559094509192509061223b8489612272565b604051339085907f141dfc18aa6a56fc816f44f0e9e2f1ebc92b15ab167770e17db5b084c10ed995905f90a3505050949350505050565b5f6003838154811061228657612286612f13565b905f5260205f20906003020190505f600182600201805490506122a99190612f3b565b8254600160601b90046001600160a01b03165f908152600660205260408120919250815460ff1660038111156122e1576122e1612bc9565b036122ff5760405163d8f2465160e01b815260040160405180910390fd5b6001815460ff16600381111561231757612317612bc9565b146125f5576003815460ff16600381111561233457612334612bc9565b03612479578460038454600184015460028501546040805192835260ff80831615156020850152610100909204909116151590820152600160601b9091046001600160a01b0316907f45c27c7ea7135714f09b069efa7497d57c38017d4e919c5535ba31dbd5b597e69060600160405180910390a46001810154600282015460405163085dd1c360e21b815260048101889052602481019290925260ff8082161515604484015261010090910416151560648201523090632177470c906084015f604051808303815f87803b15801561240b575f80fd5b505af115801561241d573d5f803e3d5ffd5b5050604051632b00f57560e11b81526004810188905260248101859052309250635601eaea91506044015f604051808303815f87803b15801561245e575f80fd5b505af1158015612470573d5f803e3d5ffd5b505050506125f5565b6002815460ff16600381111561249157612491612bc9565b036125f5575f846124a3600143612f3b565b604080519140602083015201604051602081830303815290604052805190602001205f1c6124d191906131c9565b90506004811615600280831615908890875460408051878152861515602082015285151591810191909152600160601b9091046001600160a01b0316907f45c27c7ea7135714f09b069efa7497d57c38017d4e919c5535ba31dbd5b597e69060600160405180910390a460405163085dd1c360e21b81526004810189905260248101849052821515604482015281151560648201523090632177470c906084015f604051808303815f87803b158015612588575f80fd5b505af115801561259a573d5f803e3d5ffd5b5050604051632b00f57560e11b8152600481018b905260248101889052309250635601eaea91506044015f604051808303815f87803b1580156125db575f80fd5b505af11580156125ed573d5f803e3d5ffd5b505050505050505b5050505050565b6040516001600160a01b0384811660248301528381166044830152606482018390525f91829182919088169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b179052516126609190613174565b5f604051808303815f865af19150503d805f8114612699576040519150601f19603f3d011682016040523d82523d5f602084013e61269e565b606091505b50915091508180156126c85750805115806126c85750808060200190518101906126c891906131ae565b979650505050505050565b5f805f6040845110612736575050506020810151604082015160608301516001600160601b038316158061271257506002546001600160601b03841610155b1561271c57600192505b815f0361272857600391505b80612731575060015b610d31565b50600193600393508492509050565b828054828255905f5260205f2090810192821561277e579160200282015b8281111561277e578251825591602001919060010190612763565b5061278a92915061280c565b5090565b826004810192821561277e579160200282015b8281111561277e578251829060ff169055916020019190600101906127a1565b60405180608001604052806004906020820280368337509192915050565b826004810192821561277e579160200282018281111561277e578251825591602001919060010190612763565b5b8082111561278a575f815560010161280d565b6001600160a01b03811681146120b9575f80fd5b5f60208284031215612844575f80fd5b813561284f81612820565b9392505050565b80151581146120b9575f80fd5b5f8060408385031215612874575f80fd5b82359150602083013561288681612856565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126128b4575f80fd5b604051608081018181106001600160401b03821117156128d6576128d6612891565b6040528060808401858111156128ea575f80fd5b845b818110156129045780358352602092830192016128ec565b509195945050505050565b5f805f60c08486031215612921575f80fd5b833561292c81612820565b9250602084013561293c81612820565b915061294b85604086016128a5565b90509250925092565b5f8060408385031215612965575f80fd5b823561297081612820565b946020939093013593505050565b5f6020828403121561298e575f80fd5b5035919050565b5f805f80608085870312156129a8575f80fd5b843593506020850135925060408501356129c181612856565b915060608501356129d181612856565b939692955090935050565b80356001600160601b03811681146129f2575f80fd5b919050565b5f60208284031215612a07575f80fd5b610d06826129dc565b805f5b60048110156114e9578151845260209384019390910190600101612a13565b60808101610d098284612a10565b5f805f805f805f610140888a031215612a57575f80fd5b612a60886129dc565b96506020880135612a7081612856565b955060408801359450606088013593506080880135925060a08801359150612a9b8960c08a016128a5565b905092959891949750929550565b5f8060408385031215612aba575f80fd5b8235612ac581612820565b9150602083013561288681612820565b5f82601f830112612ae4575f80fd5b81356001600160401b0380821115612afe57612afe612891565b604051601f8301601f19908116603f01168101908282118183101715612b2657612b26612891565b81604052838152866020858801011115612b3e575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215612b6e575f80fd5b8235612b7981612820565b915060208301356001600160401b03811115612b93575f80fd5b612b9f85828601612ad5565b9150509250929050565b5f8060408385031215612bba575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52602160045260245ffd5b60058110612bed57612bed612bc9565b9052565b6001600160601b03851681526001600160a01b038416602082015260808101612c1d6040830185612bdd565b821515606083015295945050505050565b5f805f8060808587031215612c41575f80fd5b8435612c4c81612820565b93506020850135925060408501356129c181612856565b5f805f60608486031215612c75575f80fd5b8335612c8081612820565b92506020840135915060408401356001600160401b03811115612ca1575f80fd5b612cad86828701612ad5565b9150509250925092565b5f8060408385031215612cc8575f80fd5b8235612cd381612820565b9150602083013561288681612856565b5f805f60608486031215612cf5575f80fd5b8335612d0081612820565b925060208401356001600160401b0381168114612d1b575f80fd5b9150604084013560ff81168114612d30575f80fd5b809150509250925092565b5f8060408385031215612d4c575f80fd5b8235915060208301356001600160401b03811115612b93575f80fd5b5f8083601f840112612d78575f80fd5b5081356001600160401b03811115612d8e575f80fd5b602083019150836020828501011115612da5575f80fd5b9250929050565b5f805f60408486031215612dbe575f80fd5b83356001600160401b03811115612dd3575f80fd5b612ddf86828701612d68565b9094509250506020840135612d3081612820565b5f805f8060808587031215612e06575f80fd5b843593506020850135925060408501356001600160401b03811115612e29575f80fd5b612e3587828801612ad5565b92505060608501356129d181612856565b60048110612bed57612bed612bc9565b60808101612e648287612e46565b602082019490945291151560408301521515606090910152919050565b5f805f805f60808688031215612e95575f80fd5b8535945060208601356001600160401b03811115612eb1575f80fd5b612ebd88828901612d68565b9095509350506040860135612ed181612820565b949793965091946060013592915050565b5f60208284031215612ef2575f80fd5b81356001600160401b03811115612f07575f80fd5b611c5a84828501612ad5565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115610d0957610d09612f27565b634e487b7160e01b5f52601260045260245ffd5b5f82612f7057612f70612f4e565b500490565b8082028115828204841417610d0957610d09612f27565b80820180821115610d0957610d09612f27565b5f610120820190508715158252602087602084015286604084015285606084015284608084015260a08301845f5b6004811015612fea57815483529183019160019182019101612fcd565b50505050979650505050505050565b5f60808201905061300e8260ff855416612e46565b60018301546020830152600283015460ff81161515604084015260ff8160081c16151560608401525092915050565b600181815b8085111561307757815f190482111561305d5761305d612f27565b8085161561306a57918102915b93841c9390800290613042565b509250929050565b5f8261308d57506001610d09565b8161309957505f610d09565b81600181146130af57600281146130b9576130d5565b6001915050610d09565b60ff8411156130ca576130ca612f27565b50506001821b610d09565b5060208310610133831016604e8410600b84101617156130f8575081810a610d09565b613102838361303d565b805f190482111561311557613115612f27565b029392505050565b5f610d0660ff84168361307f565b5f6101208201905087151582528660208301528560408301528460608301528360808301526126c860a0830184612a10565b5f6020828403121561316d575f80fd5b5051919050565b5f82515f5b818110156131935760208186018101518583015201613179565b505f920191825250919050565b60208101610d098284612bdd565b5f602082840312156131be575f80fd5b815161284f81612856565b5f826131d7576131d7612f4e565b50069056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220f2e22a0dce5ce1f5dee73c7f609484912562e77d9ae9b2964b5eeed771279c2464736f6c63430008180033", + "devdoc": { + "errors": { + "AlreadyInitialized()": [ + { + "details": "The contract is already initialized." + } + ], + "NotInitializing()": [ + { + "details": "The contract is not initializing." + } + ], + "UUPSUnauthorizedCallContext()": [ + { + "details": "The call is from an unauthorized context." + } + ], + "UUPSUnsupportedProxiableUUID(bytes32)": [ + { + "details": "The storage `slot` is unsupported as a UUID." + } + ] + }, + "events": { + "AcceptedFeeToken(address,bool)": { + "details": "To be emitted when an ERC20 token is added or removed as a method to pay fees.", + "params": { + "_accepted": "Whether the token is accepted or not.", + "_token": "The ERC20 token." + } + }, + "DisputeCreation(uint256,address)": { + "details": "To be emitted when a dispute is created.", + "params": { + "_arbitrable": "The contract which created the dispute.", + "_disputeID": "The identifier of the dispute in the Arbitrator contract." + } + }, + "Initialized(uint64)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "NewCurrencyRate(address,uint64,uint8)": { + "details": "To be emitted when the fee for a particular ERC20 token is updated.", + "params": { + "_feeToken": "The ERC20 token.", + "_rateDecimals": "The new decimals of the fee token rate.", + "_rateInEth": "The new rate of the fee token in ETH." + } + }, + "Ruling(address,uint256,uint256)": { + "details": "To be raised when a ruling is given.", + "params": { + "_arbitrable": "The arbitrable receiving the ruling.", + "_disputeID": "The identifier of the dispute in the Arbitrator contract.", + "_ruling": "The ruling which was given." + } + }, + "Upgraded(address)": { + "params": { + "newImplementation": "Address of the new implementation the proxy is now forwarding calls to." + } + } + }, + "kind": "dev", + "methods": { + "appeal(uint256,uint256,bytes,bool)": { + "details": "Appeals the ruling of a specified dispute.", + "params": { + "_disputeID": "The ID of the dispute.", + "_jump": "Whether to jump to the parent court or not." + } + }, + "appealCost(uint256,bool)": { + "details": "Gets the cost of appealing a specified dispute.", + "params": { + "_disputeID": "The ID of the dispute.", + "_jump": "Whether to jump to the parent court or not." + }, + "returns": { + "cost": "The appeal cost." + } + }, + "arbitrationCost(bytes)": { + "details": "Compute the cost of arbitration denominated in ETH. 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.", + "params": { + "_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)." + }, + "returns": { + "cost": "The arbitration cost in ETH." + } + }, + "arbitrationCost(bytes,address)": { + "details": "Compute the cost of arbitration denominated in `_feeToken`. 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.", + "params": { + "_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).", + "_feeToken": "The ERC20 token used to pay fees." + }, + "returns": { + "cost": "The arbitration cost in `_feeToken`." + } + }, + "changeAcceptedFeeTokens(address,bool)": { + "details": "Changes the supported fee tokens.", + "params": { + "_accepted": "Whether the token is supported or not as a method of fee payment.", + "_feeToken": "The fee token." + } + }, + "changeCurrencyRates(address,uint64,uint8)": { + "details": "Changes the currency rate of a fee token.", + "params": { + "_feeToken": "The fee token.", + "_rateDecimals": "The new decimals of the fee token rate.", + "_rateInEth": "The new rate of the fee token in ETH." + } + }, + "changeGovernor(address)": { + "details": "Changes the `governor` storage variable.", + "params": { + "_governor": "The new value for the `governor` storage variable." + } + }, + "changePinakion(address)": { + "details": "Changes the `pinakion` storage variable.", + "params": { + "_pinakion": "The new value for the `pinakion` storage variable." + } + }, + "constructor": { + "details": "Constructor, initializing the implementation to reduce attack surface." + }, + "createCourt(uint96,bool,uint256,uint256,uint256,uint256,uint256[4])": { + "details": "Creates a court under a specified parent court.", + "params": { + "_alpha": "The `alpha` property value of the court.", + "_feeForJuror": "The `feeForJuror` property value of the court.", + "_hiddenVotes": "The `hiddenVotes` property value of the court.", + "_jurorsForCourtJump": "The `jurorsForCourtJump` property value of the court.", + "_minStake": "The `minStake` property value of the court.", + "_parent": "The `parent` property value of the court.", + "_timesPerPeriod": "The `timesPerPeriod` property value of the court." + } + }, + "createDispute(uint256,bytes)": { + "details": "Create a dispute and pay for the fees in the native currency, typically ETH. Must be called by the arbitrable contract. Must pay at least arbitrationCost(_extraData).", + "params": { + "_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).", + "_numberOfChoices": "The number of choices the arbitrator can choose from in this dispute." + }, + "returns": { + "disputeID": "The identifier of the dispute created." + } + }, + "createDispute(uint256,bytes,address,uint256)": { + "details": "Create a dispute and pay for the fees in a supported ERC20 token. Must be called by the arbitrable contract. Must pay at least arbitrationCost(_extraData).", + "params": { + "_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).", + "_feeAmount": "Amount of the ERC20 token used to pay fees.", + "_feeToken": "The ERC20 token used to pay fees.", + "_numberOfChoices": "The number of choices the arbitrator can choose from in this dispute." + }, + "returns": { + "disputeID": "The identifier of the dispute created." + } + }, + "currentRuling(uint256)": { + "details": "Gets the current ruling of a specified dispute.", + "params": { + "_disputeID": "The ID of the dispute." + }, + "returns": { + "overridden": "Whether the ruling was overridden by appeal funding or not.", + "ruling": "The current ruling.", + "tied": "Whether it's a tie or not." + } + }, + "execute(uint256,uint256)": { + "details": "Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.", + "params": { + "_disputeID": "The ID of the dispute.", + "_round": "The appeal round." + } + }, + "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." + } + }, + "executeRuling(uint256,uint256,bool,bool)": { + "details": "Executes a specified dispute's ruling.", + "params": { + "_disputeID": "The ID of the dispute." + } + }, + "getNumberOfVotes(uint256)": { + "details": "Gets the number of votes permitted for the specified dispute in the latest round.", + "params": { + "_disputeID": "The ID of the dispute." + } + }, + "initialize(address,address,uint256[4])": { + "details": "Initializer (constructor equivalent for upgradable contracts).", + "params": { + "_courtParameters": "Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).", + "_governor": "The governor's address.", + "_pinakion": "The address of the token contract." + } + }, + "proxiableUUID()": { + "details": "Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.", + "params": { + "data": "Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.", + "newImplementation": "Address of the new implementation contract." + } + } + }, + "title": "KlerosCoreRuler Core arbitrator contract for development and testing purposes.", + "version": 1 + }, + "userdoc": { + "errors": { + "FailedDelegateCall()": [ + { + "notice": "Failed Delegated call" + } + ], + "InvalidImplementation(address)": [ + { + "notice": "The `implementation` is not UUPS-compliant" + } + ] + }, + "events": { + "Upgraded(address)": { + "notice": "Emitted when the `implementation` has been successfully upgraded." + } + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 14410, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 14413, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "pinakion", + "offset": 0, + "slot": "1", + "type": "t_contract(IERC20)1229" + }, + { + "astId": 14417, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "courts", + "offset": 0, + "slot": "2", + "type": "t_array(t_struct(Court)14361_storage)dyn_storage" + }, + { + "astId": 14421, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "disputes", + "offset": 0, + "slot": "3", + "type": "t_array(t_struct(Dispute)14376_storage)dyn_storage" + }, + { + "astId": 14427, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "currencyRates", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_contract(IERC20)1229,t_struct(CurrencyRate)14391_storage)" + }, + { + "astId": 14432, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "rulers", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_contract(IArbitrableV2)21560,t_address)" + }, + { + "astId": 14438, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "settings", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_contract(IArbitrableV2)21560,t_struct(RulerSettings)14339_storage)" + }, + { + "astId": 14443, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "rulingResults", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_uint256,t_struct(RulingResult)14398_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Court)14361_storage)dyn_storage": { + "base": "t_struct(Court)14361_storage", + "encoding": "dynamic_array", + "label": "struct KlerosCoreRuler.Court[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(Dispute)14376_storage)dyn_storage": { + "base": "t_struct(Dispute)14376_storage", + "encoding": "dynamic_array", + "label": "struct KlerosCoreRuler.Dispute[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(Round)14384_storage)dyn_storage": { + "base": "t_struct(Round)14384_storage", + "encoding": "dynamic_array", + "label": "struct KlerosCoreRuler.Round[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)4_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[4]", + "numberOfBytes": "128" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IArbitrableV2)21560": { + "encoding": "inplace", + "label": "contract IArbitrableV2", + "numberOfBytes": "20" + }, + "t_contract(IERC20)1229": { + "encoding": "inplace", + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_enum(Period)14329": { + "encoding": "inplace", + "label": "enum KlerosCoreRuler.Period", + "numberOfBytes": "1" + }, + "t_enum(RulingMode)14323": { + "encoding": "inplace", + "label": "enum KlerosCoreRuler.RulingMode", + "numberOfBytes": "1" + }, + "t_mapping(t_contract(IArbitrableV2)21560,t_address)": { + "encoding": "mapping", + "key": "t_contract(IArbitrableV2)21560", + "label": "mapping(contract IArbitrableV2 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_contract(IArbitrableV2)21560,t_struct(RulerSettings)14339_storage)": { + "encoding": "mapping", + "key": "t_contract(IArbitrableV2)21560", + "label": "mapping(contract IArbitrableV2 => struct KlerosCoreRuler.RulerSettings)", + "numberOfBytes": "32", + "value": "t_struct(RulerSettings)14339_storage" + }, + "t_mapping(t_contract(IERC20)1229,t_struct(CurrencyRate)14391_storage)": { + "encoding": "mapping", + "key": "t_contract(IERC20)1229", + "label": "mapping(contract IERC20 => struct KlerosCoreRuler.CurrencyRate)", + "numberOfBytes": "32", + "value": "t_struct(CurrencyRate)14391_storage" + }, + "t_mapping(t_uint256,t_struct(RulingResult)14398_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct KlerosCoreRuler.RulingResult)", + "numberOfBytes": "32", + "value": "t_struct(RulingResult)14398_storage" + }, + "t_struct(Court)14361_storage": { + "encoding": "inplace", + "label": "struct KlerosCoreRuler.Court", + "members": [ + { + "astId": 14341, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "parent", + "offset": 0, + "slot": "0", + "type": "t_uint96" + }, + { + "astId": 14343, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "hiddenVotes", + "offset": 12, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 14346, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "children", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 14348, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "minStake", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 14350, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "alpha", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 14352, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "feeForJuror", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 14354, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "jurorsForCourtJump", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 14358, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "timesPerPeriod", + "offset": 0, + "slot": "6", + "type": "t_array(t_uint256)4_storage" + }, + { + "astId": 14360, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "disabled", + "offset": 0, + "slot": "10", + "type": "t_bool" + } + ], + "numberOfBytes": "352" + }, + "t_struct(CurrencyRate)14391_storage": { + "encoding": "inplace", + "label": "struct KlerosCoreRuler.CurrencyRate", + "members": [ + { + "astId": 14386, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "feePaymentAccepted", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 14388, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "rateInEth", + "offset": 1, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 14390, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "rateDecimals", + "offset": 9, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Dispute)14376_storage": { + "encoding": "inplace", + "label": "struct KlerosCoreRuler.Dispute", + "members": [ + { + "astId": 14363, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "courtID", + "offset": 0, + "slot": "0", + "type": "t_uint96" + }, + { + "astId": 14366, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "arbitrated", + "offset": 12, + "slot": "0", + "type": "t_contract(IArbitrableV2)21560" + }, + { + "astId": 14369, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "period", + "offset": 0, + "slot": "1", + "type": "t_enum(Period)14329" + }, + { + "astId": 14371, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "ruled", + "offset": 1, + "slot": "1", + "type": "t_bool" + }, + { + "astId": 14375, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "rounds", + "offset": 0, + "slot": "2", + "type": "t_array(t_struct(Round)14384_storage)dyn_storage" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Round)14384_storage": { + "encoding": "inplace", + "label": "struct KlerosCoreRuler.Round", + "members": [ + { + "astId": 14378, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "totalFeesForJurors", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 14380, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "sumFeeRewardPaid", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 14383, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "feeToken", + "offset": 0, + "slot": "2", + "type": "t_contract(IERC20)1229" + } + ], + "numberOfBytes": "96" + }, + "t_struct(RulerSettings)14339_storage": { + "encoding": "inplace", + "label": "struct KlerosCoreRuler.RulerSettings", + "members": [ + { + "astId": 14332, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "rulingMode", + "offset": 0, + "slot": "0", + "type": "t_enum(RulingMode)14323" + }, + { + "astId": 14334, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "presetRuling", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 14336, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "presetTied", + "offset": 0, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 14338, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "presetOverridden", + "offset": 1, + "slot": "2", + "type": "t_bool" + } + ], + "numberOfBytes": "96" + }, + "t_struct(RulingResult)14398_storage": { + "encoding": "inplace", + "label": "struct KlerosCoreRuler.RulingResult", + "members": [ + { + "astId": 14393, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "ruling", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 14395, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "tied", + "offset": 0, + "slot": "1", + "type": "t_bool" + }, + { + "astId": 14397, + "contract": "src/arbitration/devtools/KlerosCoreRuler.sol:KlerosCoreRuler", + "label": "overridden", + "offset": 1, + "slot": "1", + "type": "t_bool" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + }, + "t_uint96": { + "encoding": "inplace", + "label": "uint96", + "numberOfBytes": "12" + } + } + } +} diff --git a/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler_Proxy.json b/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler_Proxy.json new file mode 100644 index 000000000..bff9fda17 --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/KlerosCoreRuler_Proxy.json @@ -0,0 +1,107 @@ +{ + "address": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "transactionIndex": 1, + "gasUsed": "366202", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000040000000000000100005000000000000000000000000000040008000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000060000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4a74c33b3212cc7ed833956036b191ca451ae191619b2e4f90cf6dad50868d33", + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 81776148, + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "address": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "topics": [ + "0x0c907a651f88974ed0d9423aacc8b998c40eedf39920e2c3bdae0adcc486a761", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0x4a74c33b3212cc7ed833956036b191ca451ae191619b2e4f90cf6dad50868d33" + }, + { + "transactionIndex": 1, + "blockNumber": 81776148, + "transactionHash": "0xe7a285a9dae297998d65ab557226558d250c1e0b512f0d9349fc4e3f5c9c3865", + "address": "0x7ffcd32A0521645E6fCFd071A68F0e26957775a5", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 1, + "blockHash": "0x4a74c33b3212cc7ed833956036b191ca451ae191619b2e4f90cf6dad50868d33" + } + ], + "blockNumber": 81776148, + "cumulativeGasUsed": "366202", + "status": 1, + "byzantium": true + }, + "args": [ + "0x97e30A3A940856A3913437912C746f1aF6ccC76c", + "0x05d3177d000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c5900000000000000000000000034b944d42cacfc8266955d07a80181d2054aa22500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000010" + ], + "numDeployments": 1, + "solcInputHash": "2c1a31d10a5f76f480d447fbb502d6fc", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Simon Malatrait \",\"details\":\"This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Initializes the upgradeable proxy with an initial implementation specified by `_implementation`. If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\"}},\"stateVariables\":{\"IMPLEMENTATION_SLOT\":{\"details\":\"Storage slot with the address of the current implementation. This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is validated in the constructor. NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\"}},\"title\":\"UUPS Proxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/UUPSProxy.sol\":\"UUPSProxy\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n// Adapted from \\n\\n/**\\n * @authors: [@malatrax]\\n * @reviewers: []\\n * @auditors: []\\n * @bounties: []\\n * @deployments: []\\n */\\npragma solidity 0.8.24;\\n\\n/**\\n * @title UUPS Proxy\\n * @author Simon Malatrait \\n * @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n * @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n * @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n */\\ncontract UUPSProxy {\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n * NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0x7aa5f14ce351299722ac1a1afca9e65e1c795f32ea3e9702b0d5faaf7ca822a0\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561000f575f80fd5b506040516102e53803806102e583398101604081905261002e91610143565b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5580515f14610106575f826001600160a01b031682604051610072919061020b565b5f60405180830381855af49150503d805f81146100aa576040519150601f19603f3d011682016040523d82523d5f602084013e6100af565b606091505b50509050806101045760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050610226565b634e487b7160e01b5f52604160045260245ffd5b5f5b8381101561013b578181015183820152602001610123565b50505f910152565b5f8060408385031215610154575f80fd5b82516001600160a01b038116811461016a575f80fd5b60208401519092506001600160401b0380821115610186575f80fd5b818501915085601f830112610199575f80fd5b8151818111156101ab576101ab61010d565b604051601f8201601f19908116603f011681019083821181831017156101d3576101d361010d565b816040528281528860208487010111156101eb575f80fd5b6101fc836020830160208801610121565b80955050505050509250929050565b5f825161021c818460208701610121565b9190910192915050565b60b3806102325f395ff3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b365f80375f80365f845af43d5f803e8080156079573d5ff35b3d5ffdfea2646970667358221220cef4b52606e73de407a2e27987280e32ca63601b58f184d7d171ca05e6a91f7c64736f6c63430008180033", + "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b365f80375f80365f845af43d5f803e8080156079573d5ff35b3d5ffdfea2646970667358221220cef4b52606e73de407a2e27987280e32ca63601b58f184d7d171ca05e6a91f7c64736f6c63430008180033", + "devdoc": { + "author": "Simon Malatrait ", + "details": "This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.We refer to the Proxiable contract (as per ERC-1822) with `implementation`.", + "kind": "dev", + "methods": { + "constructor": { + "details": "Initializes the upgradeable proxy with an initial implementation specified by `_implementation`. If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor." + } + }, + "stateVariables": { + "IMPLEMENTATION_SLOT": { + "details": "Storage slot with the address of the current implementation. This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is validated in the constructor. NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)" + } + }, + "title": "UUPS Proxy", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/contracts/src/arbitration/CentralizedArbitrator.sol b/contracts/src/arbitration/CentralizedArbitrator.sol deleted file mode 100644 index efb5825e3..000000000 --- a/contracts/src/arbitration/CentralizedArbitrator.sol +++ /dev/null @@ -1,378 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {IArbitrableV2, IArbitratorV2, IERC20} from "./interfaces/IArbitratorV2.sol"; - -/// @title Centralized Arbitrator -/// @dev This is a centralized arbitrator deciding alone on the result of disputes. It illustrates how IArbitratorV2 interface can be implemented. -/// Note that this contract supports appeals. The ruling given by the arbitrator can be appealed by crowdfunding a desired choice. -contract CentralizedArbitrator is IArbitratorV2 { - // ************************************* // - // * Enums / Structs * // - // ************************************* // - - enum DisputeStatus { - Waiting, // The dispute is waiting for the ruling or not created. - Appealable, // The dispute can be appealed. - Solved // The dispute is resolved. - } - - struct DisputeStruct { - IArbitrableV2 arbitrated; // The address of the arbitrable contract. - bytes arbitratorExtraData; // Extra data for the arbitrator. - uint256 choices; // The number of choices the arbitrator can choose from. - uint256 appealPeriodStart; // Time when the appeal funding becomes possible. - uint256 arbitrationFee; // Fee paid by the arbitrable for the arbitration. Must be equal or higher than arbitration cost. - uint256 ruling; // Ruling given by the arbitrator. - DisputeStatus status; // A current status of the dispute. - } - - struct Round { - mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round. - mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise. - mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice. - uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute. - uint256[] fundedChoices; // Stores the choices that are fully funded. - } - - // ************************************* // - // * Storage * // - // ************************************* // - - // The required fee stake that a party must pay depends on who won the previous round and is proportional to the appeal cost such that the fee stake for a round is stake multiplier * appeal cost for that round. - 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. - 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. - 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. - uint256 public constant MULTIPLIER_DIVISOR = 10000; - address public owner = msg.sender; // Owner of the contract. - uint256 public appealDuration; // The duration of the appeal period. - - uint256 private arbitrationFee; // The cost to create a dispute. Made private because of the arbitrationCost() getter. - uint256 public appealFee; // The cost to fund one of the choices, not counting the additional fee stake amount. - - DisputeStruct[] public disputes; // Stores the dispute info. disputes[disputeID]. - mapping(uint256 => Round[]) public disputeIDtoRoundArray; // Maps dispute IDs to Round array that contains the info about crowdfunding. - - // ************************************* // - // * Events * // - // ************************************* // - - /// @dev To be emitted when a dispute can be appealed. - /// @param _disputeID ID of the dispute. - /// @param _arbitrable The contract which created the dispute. - event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable); - - /// @dev To be emitted when the current ruling is appealed. - /// @param _disputeID ID of the dispute. - /// @param _arbitrable The contract which created the dispute. - event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable); - - /// @dev Raised when a contribution is made, inside fundAppeal function. - /// @param _disputeID ID of the dispute. - /// @param _round The round the contribution was made to. - /// @param _choice Indicates the choice option which got the contribution. - /// @param _contributor Caller of fundAppeal function. - /// @param _amount Contribution amount. - event Contribution( - uint256 indexed _disputeID, - uint256 indexed _round, - uint256 _choice, - address indexed _contributor, - uint256 _amount - ); - - /// @dev Raised when a contributor withdraws a non-zero value. - /// @param _disputeID ID of the dispute. - /// @param _round The round the withdrawal was made from. - /// @param _choice Indicates the choice which contributor gets rewards from. - /// @param _contributor The beneficiary of the withdrawal. - /// @param _amount Total withdrawn amount, consists of reimbursed deposits and rewards. - event Withdrawal( - uint256 indexed _disputeID, - uint256 indexed _round, - uint256 _choice, - address indexed _contributor, - uint256 _amount - ); - - /// @dev To be raised when a choice is fully funded for appeal. - /// @param _disputeID ID of the dispute. - /// @param _round ID of the round where the choice was funded. - /// @param _choice The choice that just got fully funded. - event ChoiceFunded(uint256 indexed _disputeID, uint256 indexed _round, uint256 indexed _choice); - - // ************************************* // - // * Function Modifiers * // - // ************************************* // - - modifier onlyOwner() { - require(msg.sender == owner, "Can only be called by the owner."); - _; - } - - // ************************************* // - // * Constructor * // - // ************************************* // - - /// @dev Constructor. - /// @param _arbitrationFee Amount to be paid for arbitration. - /// @param _appealDuration Duration of the appeal period. - /// @param _appealFee Amount to be paid to fund one of the appeal choices, not counting the additional fee stake amount. - constructor(uint256 _arbitrationFee, uint256 _appealDuration, uint256 _appealFee) { - arbitrationFee = _arbitrationFee; - appealDuration = _appealDuration; - appealFee = _appealFee; - } - - // ************************************* // - // * Governance * // - // ************************************* // - - /// @dev Set the arbitration fee. Only callable by the owner. - /// @param _arbitrationFee Amount to be paid for arbitration. - function setArbitrationFee(uint256 _arbitrationFee) external onlyOwner { - arbitrationFee = _arbitrationFee; - } - - /// @dev Set the duration of the appeal period. Only callable by the owner. - /// @param _appealDuration New duration of the appeal period. - function setAppealDuration(uint256 _appealDuration) external onlyOwner { - appealDuration = _appealDuration; - } - - /// @dev Set the appeal fee. Only callable by the owner. - /// @param _appealFee Amount to be paid for appeal. - function setAppealFee(uint256 _appealFee) external onlyOwner { - appealFee = _appealFee; - } - - // ************************************* // - // * State Modifiers * // - // ************************************* // - - /// @inheritdoc IArbitratorV2 - function createDispute( - uint256 _choices, - bytes calldata _extraData - ) external payable override returns (uint256 disputeID) { - require(msg.value >= arbitrationCost(_extraData), "Arbitration fees: not enough."); - disputeID = disputes.length; - disputes.push( - DisputeStruct({ - arbitrated: IArbitrableV2(msg.sender), - arbitratorExtraData: _extraData, - choices: _choices, - appealPeriodStart: 0, - arbitrationFee: msg.value, - ruling: 0, - status: DisputeStatus.Waiting - }) - ); - - disputeIDtoRoundArray[disputeID].push(); - emit DisputeCreation(disputeID, IArbitrableV2(msg.sender)); - } - - /// @inheritdoc IArbitratorV2 - function createDispute( - uint256 /*_choices*/, - bytes calldata /*_extraData*/, - IERC20 /*_feeToken*/, - uint256 /*_feeAmount*/ - ) external pure override returns (uint256) { - revert("Not supported"); - } - - /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded. This function allows the appeals to be crowdfunded. - /// Note that the surplus deposit will be reimbursed. - /// @param _disputeID Index of the dispute to appeal. - /// @param _choice A choice that receives funding. - function fundAppeal(uint256 _disputeID, uint256 _choice) external payable { - DisputeStruct storage dispute = disputes[_disputeID]; - require(dispute.status == DisputeStatus.Appealable, "Dispute not appealable."); - require(_choice <= dispute.choices, "There is no such ruling to fund."); - - (uint256 appealPeriodStart, uint256 appealPeriodEnd) = appealPeriod(_disputeID); - require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, "Appeal period is over."); - - uint256 multiplier; - if (dispute.ruling == _choice) { - multiplier = WINNER_STAKE_MULTIPLIER; - } else { - require( - block.timestamp - appealPeriodStart < - ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / MULTIPLIER_DIVISOR, - "Appeal period is over for loser" - ); - multiplier = LOSER_STAKE_MULTIPLIER; - } - - Round[] storage rounds = disputeIDtoRoundArray[_disputeID]; - uint256 lastRoundIndex = rounds.length - 1; - Round storage lastRound = rounds[lastRoundIndex]; - require(!lastRound.hasPaid[_choice], "Appeal fee is already paid."); - - uint256 totalCost = appealFee + (appealFee * multiplier) / MULTIPLIER_DIVISOR; - - // Take up to the amount necessary to fund the current round at the current costs. - uint256 contribution; - if (totalCost > lastRound.paidFees[_choice]) { - contribution = totalCost - lastRound.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level. - ? msg.value - : totalCost - lastRound.paidFees[_choice]; - emit Contribution(_disputeID, lastRoundIndex, _choice, msg.sender, contribution); - } - - lastRound.contributions[msg.sender][_choice] += contribution; - lastRound.paidFees[_choice] += contribution; - if (lastRound.paidFees[_choice] >= totalCost) { - lastRound.feeRewards += lastRound.paidFees[_choice]; - lastRound.fundedChoices.push(_choice); - lastRound.hasPaid[_choice] = true; - emit ChoiceFunded(_disputeID, lastRoundIndex, _choice); - } - - if (lastRound.fundedChoices.length > 1) { - // At least two sides are fully funded. - rounds.push(); - lastRound.feeRewards = lastRound.feeRewards - appealFee; - - dispute.status = DisputeStatus.Waiting; - dispute.appealPeriodStart = 0; - emit AppealDecision(_disputeID, dispute.arbitrated); - } - - if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution); - } - - /// @dev Give a ruling to a dispute. Once it's given the dispute can be appealed, and after the appeal period has passed this function should be called again to finalize the ruling. - /// Accounts for the situation where the winner loses a case due to paying less appeal fees than expected. - /// @param _disputeID ID of the dispute to rule. - /// @param _ruling Ruling given by the arbitrator. Note that 0 means that arbitrator chose "Refused to rule". - function giveRuling(uint256 _disputeID, uint256 _ruling) external onlyOwner { - DisputeStruct storage dispute = disputes[_disputeID]; - require(_ruling <= dispute.choices, "Invalid ruling."); - require(dispute.status != DisputeStatus.Solved, "The dispute must not be solved."); - - if (dispute.status == DisputeStatus.Waiting) { - dispute.ruling = _ruling; - dispute.status = DisputeStatus.Appealable; - dispute.appealPeriodStart = block.timestamp; - emit AppealPossible(_disputeID, dispute.arbitrated); - } else { - require(block.timestamp > dispute.appealPeriodStart + appealDuration, "Appeal period not passed yet."); - dispute.ruling = _ruling; - dispute.status = DisputeStatus.Solved; - - Round[] storage rounds = disputeIDtoRoundArray[_disputeID]; - Round storage lastRound = rounds[rounds.length - 1]; - // If only one ruling option is funded, it wins by default. Note that if any other ruling had funded, an appeal would have been created. - if (lastRound.fundedChoices.length == 1) { - dispute.ruling = lastRound.fundedChoices[0]; - } - - payable(msg.sender).send(dispute.arbitrationFee); // Avoid blocking. - dispute.arbitrated.rule(_disputeID, dispute.ruling); - } - } - - /// @dev Allows to withdraw any reimbursable fees or rewards after the dispute gets resolved. - /// @param _disputeID Index of the dispute in disputes array. - /// @param _beneficiary The address which rewards to withdraw. - /// @param _round The round the caller wants to withdraw from. - /// @param _choice The ruling option that the caller wants to withdraw from. - /// @return amount The withdrawn amount. - function withdrawFeesAndRewards( - uint256 _disputeID, - address payable _beneficiary, - uint256 _round, - uint256 _choice - ) external returns (uint256 amount) { - DisputeStruct storage dispute = disputes[_disputeID]; - require(dispute.status == DisputeStatus.Solved, "Dispute should be resolved."); - Round storage round = disputeIDtoRoundArray[_disputeID][_round]; - - if (!round.hasPaid[_choice]) { - // Allow to reimburse if funding was unsuccessful for this ruling option. - amount = round.contributions[_beneficiary][_choice]; - } else { - // Funding was successful for this ruling option. - if (_choice == dispute.ruling) { - // This ruling option is the ultimate winner. - amount = round.paidFees[_choice] > 0 - ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice] - : 0; - } else if (!round.hasPaid[dispute.ruling]) { - // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed. - amount = - (round.contributions[_beneficiary][_choice] * round.feeRewards) / - (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]); - } - } - round.contributions[_beneficiary][_choice] = 0; - - if (amount != 0) { - _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH. - emit Withdrawal(_disputeID, _round, _choice, _beneficiary, amount); - } - } - - // ************************************* // - // * Public Views * // - // ************************************* // - - /// @inheritdoc IArbitratorV2 - function arbitrationCost(bytes calldata /*_extraData*/) public view override returns (uint256 fee) { - return arbitrationFee; - } - - /// @inheritdoc IArbitratorV2 - function arbitrationCost( - bytes calldata /*_extraData*/, - IERC20 /*_feeToken*/ - ) public pure override returns (uint256 /*cost*/) { - revert("Not supported"); - } - - /// @dev Return the funded amount and funding goal for one of the choices. - /// @param _disputeID The ID of the dispute to appeal. - /// @param _choice The choice to check the funding status of. - /// @return funded The amount funded so far for this choice in wei. - /// @return goal The amount to fully fund this choice in wei. - function fundingStatus(uint256 _disputeID, uint256 _choice) external view returns (uint256 funded, uint256 goal) { - DisputeStruct storage dispute = disputes[_disputeID]; - require(_choice <= dispute.choices, "There is no such ruling to fund."); - require(dispute.status == DisputeStatus.Appealable, "Dispute not appealable."); - - if (dispute.ruling == _choice) { - goal = appealFee + (appealFee * WINNER_STAKE_MULTIPLIER) / MULTIPLIER_DIVISOR; - } else { - goal = appealFee + (appealFee * LOSER_STAKE_MULTIPLIER) / MULTIPLIER_DIVISOR; - } - - Round[] storage rounds = disputeIDtoRoundArray[_disputeID]; - Round storage lastRound = rounds[rounds.length - 1]; - - return (lastRound.paidFees[_choice], goal); - } - - /// @dev Compute the start and end of the dispute's appeal period, if possible. If the dispute is not appealble return (0, 0). - /// @param _disputeID ID of the dispute. - /// @return start The start of the period. - /// @return end The end of the period. - function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) { - DisputeStruct storage dispute = disputes[_disputeID]; - if (dispute.status == DisputeStatus.Appealable) { - start = dispute.appealPeriodStart; - end = start + appealDuration; - } - return (start, end); - } - - function currentRuling( - uint256 /*_disputeID*/ - ) public pure returns (uint256 /*ruling*/, bool /*tied*/, bool /*overridden*/) { - revert("Not supported"); - } -} diff --git a/contracts/src/arbitration/devtools/DisputeResolverRuler.sol b/contracts/src/arbitration/devtools/DisputeResolverRuler.sol index c450abe01..34b2498b0 100644 --- a/contracts/src/arbitration/devtools/DisputeResolverRuler.sol +++ b/contracts/src/arbitration/devtools/DisputeResolverRuler.sol @@ -13,8 +13,9 @@ interface IKlerosCoreRulerFragment { function getNextDisputeID() external view returns (uint256); } -/// @title DisputeResolver -/// DisputeResolver contract adapted for V2 from https://github.com/kleros/arbitrable-proxy-contracts/blob/master/contracts/ArbitrableProxy.sol. +/// @title DisputeResolverRuler +/// It extends DisputeResolver for testing purposes of the automatic ruling modes. +/// The arbitrator disputeID must be known before dispute creation, otherwise the dispute cannot be retrieved during the immediate call to rule(). contract DisputeResolverRuler is DisputeResolver { // ************************************* // // * Constructor * // @@ -47,6 +48,7 @@ contract DisputeResolverRuler is DisputeResolver { dispute.arbitratorExtraData = _arbitratorExtraData; dispute.numberOfRulingOptions = _numberOfRulingOptions; + // Keep track of the upcoming dispute ID before dispute creation, so rule() can be called immediately after. disputeID = IKlerosCoreRulerFragment(address(arbitrator)).getNextDisputeID(); arbitratorDisputeIDToLocalID[disputeID] = localDisputeID; uint256 templateId = templateRegistry.setDisputeTemplate("", _disputeTemplate, _disputeTemplateDataMappings); diff --git a/contracts/src/arbitration/devtools/KlerosCoreRuler.sol b/contracts/src/arbitration/devtools/KlerosCoreRuler.sol index bd3bf0816..3c5aebf8b 100644 --- a/contracts/src/arbitration/devtools/KlerosCoreRuler.sol +++ b/contracts/src/arbitration/devtools/KlerosCoreRuler.sol @@ -338,8 +338,9 @@ contract KlerosCoreRuler is IArbitratorV2, UUPSProxiable, Initializable { // * State Modifiers * // // ************************************* // - function changeRulingModeToManual(IArbitrableV2 _arbitrable) external onlyByGovernor { - if (rulers[_arbitrable] != msg.sender && rulers[_arbitrable] != address(0)) revert RulerOnly(); + function changeRulingModeToManual(IArbitrableV2 _arbitrable) external { + if (rulers[_arbitrable] == address(0)) rulers[_arbitrable] = msg.sender; + if (rulers[_arbitrable] != msg.sender) revert RulerOnly(); delete settings[_arbitrable]; RulerSettings storage arbitratedSettings = settings[_arbitrable]; @@ -347,8 +348,9 @@ contract KlerosCoreRuler is IArbitratorV2, UUPSProxiable, Initializable { emit RulerSettingsChanged(_arbitrable, arbitratedSettings); } - function changeRulingModeToAutomaticRandom(IArbitrableV2 _arbitrable) external onlyByGovernor { - if (rulers[_arbitrable] != msg.sender && rulers[_arbitrable] != address(0)) revert RulerOnly(); + function changeRulingModeToAutomaticRandom(IArbitrableV2 _arbitrable) external { + if (rulers[_arbitrable] == address(0)) rulers[_arbitrable] = msg.sender; + if (rulers[_arbitrable] != msg.sender) revert RulerOnly(); delete settings[_arbitrable]; RulerSettings storage arbitratedSettings = settings[_arbitrable]; @@ -361,8 +363,9 @@ contract KlerosCoreRuler is IArbitratorV2, UUPSProxiable, Initializable { uint256 _presetRuling, bool _presetTied, bool _presetOverridden - ) external onlyByGovernor { - if (rulers[_arbitrable] != msg.sender && rulers[_arbitrable] != address(0)) revert RulerOnly(); + ) external { + if (rulers[_arbitrable] == address(0)) rulers[_arbitrable] = msg.sender; + if (rulers[_arbitrable] != msg.sender) revert RulerOnly(); delete settings[_arbitrable]; RulerSettings storage arbitratedSettings = settings[_arbitrable]; @@ -419,7 +422,6 @@ contract KlerosCoreRuler is IArbitratorV2, UUPSProxiable, Initializable { round.totalFeesForJurors = _feeAmount; round.feeToken = IERC20(_feeToken); - rulers[dispute.arbitrated] = tx.origin; _autoRule(disputeID, _numberOfChoices); emit DisputeCreation(disputeID, IArbitrableV2(msg.sender)); diff --git a/contracts/test/arbitration/ruler.ts b/contracts/test/arbitration/ruler.ts index 0e872f97f..bcbc7310f 100644 --- a/contracts/test/arbitration/ruler.ts +++ b/contracts/test/arbitration/ruler.ts @@ -6,7 +6,7 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; describe("KlerosCoreRuler", async () => { // eslint-disable-next-line no-unused-vars - let deployer; + let deployer, dev, dev2; let core: KlerosCoreRuler; let resolver: DisputeResolver; @@ -23,7 +23,7 @@ describe("KlerosCoreRuler", async () => { "0000000000000000000000000000000000000000000000000000000000000003"; // minJurors 3 before("Deploying", async () => { - [deployer] = await ethers.getSigners(); + [deployer, dev, dev2] = await ethers.getSigners(); [core, resolver] = await deployContracts(deployer); }); @@ -44,8 +44,34 @@ describe("KlerosCoreRuler", async () => { ).to.be.revertedWithCustomError(core, "RulingModeNotSet"); }); + it("Should allow anyone to set the RulingMode for an uninitialized arbitrable", async () => { + expect(await core.rulers(resolver.address)).to.equal(ethers.constants.AddressZero); + + await expect(core.connect(dev).changeRulingModeToAutomaticRandom(resolver.address)) + .to.emit(core, "RulerSettingsChanged") + .withArgs(resolver.address, [RulingMode.automaticRandom, 0, false, false]); + + expect(await core.rulers(resolver.address)).to.equal(dev.address); + }); + + it("Should only allow the arbitrable's ruler to set the RulingMode", async () => { + expect(await core.rulers(resolver.address)).to.equal(dev.address); + + await expect(core.connect(dev2).changeRulingModeToManual(resolver.address)).revertedWithCustomError( + core, + "RulerOnly" + ); + + await expect(core.connect(deployer).changeRulingModeToManual(resolver.address)).revertedWithCustomError( + core, + "RulerOnly" + ); + + expect(await core.rulers(resolver.address)).to.equal(dev.address); + }); + it("Should create a dispute and automatically execute a random ruling", async () => { - await expect(core.changeRulingModeToAutomaticRandom(resolver.address)) + await expect(core.connect(dev).changeRulingModeToAutomaticRandom(resolver.address)) .to.emit(core, "RulerSettingsChanged") .withArgs(resolver.address, [RulingMode.automaticRandom, 0, false, false]); @@ -59,7 +85,7 @@ describe("KlerosCoreRuler", async () => { .and.to.emit(core, "Ruling") .withArgs(resolver.address, disputeID, anyValue) .and.to.emit(core, "TokenAndETHShift") - .withArgs(deployer.address, disputeID, 0, 1, 0, anyValue, ethers.constants.AddressZero) + .withArgs(dev.address, disputeID, 0, 1, 0, anyValue, ethers.constants.AddressZero) .and.to.emit(resolver, "DisputeRequest") .withArgs(core.address, disputeID, disputeID, disputeID, "") .and.to.emit(resolver, "Ruling") @@ -67,7 +93,7 @@ describe("KlerosCoreRuler", async () => { }); it("Should create a dispute and automatically execute a preset ruling", async () => { - await expect(core.changeRulingModeToAutomaticPreset(resolver.address, 2, true, false)) + await expect(core.connect(dev).changeRulingModeToAutomaticPreset(resolver.address, 2, true, false)) .to.emit(core, "RulerSettingsChanged") .withArgs(resolver.address, [RulingMode.automaticPreset, 2, true, false]); @@ -81,7 +107,7 @@ describe("KlerosCoreRuler", async () => { .and.to.emit(core, "Ruling") .withArgs(resolver.address, disputeID, 2) .and.to.emit(core, "TokenAndETHShift") - .withArgs(deployer.address, disputeID, 0, 1, 0, anyValue, ethers.constants.AddressZero) + .withArgs(dev.address, disputeID, 0, 1, 0, anyValue, ethers.constants.AddressZero) .and.to.emit(resolver, "DisputeRequest") .withArgs(core.address, disputeID, disputeID, disputeID, "") .and.to.emit(resolver, "Ruling") @@ -89,7 +115,7 @@ describe("KlerosCoreRuler", async () => { }); it("Should create a dispute and manually execute a ruling", async () => { - await expect(core.changeRulingModeToManual(resolver.address)) + await expect(core.connect(dev).changeRulingModeToManual(resolver.address)) .to.emit(core, "RulerSettingsChanged") .withArgs(resolver.address, [RulingMode.manual, 0, false, false]); @@ -101,7 +127,12 @@ describe("KlerosCoreRuler", async () => { .and.to.emit(resolver, "DisputeRequest") .withArgs(core.address, disputeID, disputeID, disputeID, ""); - await expect(core.executeRuling(disputeID, 3, true, true)) + await expect(core.connect(deployer).executeRuling(disputeID, 3, true, true)).revertedWithCustomError( + core, + "RulerOnly" + ); + + await expect(core.connect(dev).executeRuling(disputeID, 3, true, true)) .and.to.emit(core, "Ruling") .withArgs(resolver.address, disputeID, 3) .and.to.emit(resolver, "Ruling") @@ -109,7 +140,7 @@ describe("KlerosCoreRuler", async () => { await expect(core.execute(disputeID, 0)) .and.to.emit(core, "TokenAndETHShift") - .withArgs(deployer.address, disputeID, 0, 1, 0, anyValue, ethers.constants.AddressZero); + .withArgs(dev.address, disputeID, 0, 1, 0, anyValue, ethers.constants.AddressZero); }); }); diff --git a/contracts/test/evidence/index.ts b/contracts/test/evidence/index.ts index 40c3d7bf8..2f3178624 100644 --- a/contracts/test/evidence/index.ts +++ b/contracts/test/evidence/index.ts @@ -1,6 +1,7 @@ import { expect } from "chai"; -import { ethers } from "hardhat"; +import { deployments, ethers } from "hardhat"; import { BigNumber } from "ethers"; +import { DisputeTemplateRegistry, KlerosCore, KlerosCoreRuler, ModeratedEvidenceModule } from "../../typechain-types"; const hre = require("hardhat"); const Party = { @@ -16,7 +17,10 @@ function getEmittedEvent(eventName: any, receipt: any) { describe("Home Evidence contract", async () => { const arbitrationFee = 1000; const appealFee = arbitrationFee; - const arbitratorExtraData = "0x85"; + const arbitratorExtraData = ethers.utils.defaultAbiCoder.encode( + ["uint256", "uint256"], + [1, 1] // courtId 1, minJurors 1 + ); const appealTimeout = 100; const bondTimeout = 60 * 10; const totalCostMultiplier = 15000; @@ -34,18 +38,30 @@ describe("Home Evidence contract", async () => { let user4; let evidenceID; - let arbitrator; - let evidenceModule; - let disputeTemplateRegistry; + let arbitrator: KlerosCore; + let evidenceModule: ModeratedEvidenceModule; + let disputeTemplateRegistry: DisputeTemplateRegistry; beforeEach("Setup contracts", async () => { [deployer, user1, user2, user3, user4] = await ethers.getSigners(); - const Arbitrator = await ethers.getContractFactory("CentralizedArbitrator"); - arbitrator = await Arbitrator.deploy(String(arbitrationFee), appealTimeout, String(appealFee)); - - const DisputeTemplateRegistry = await ethers.getContractFactory("DisputeTemplateRegistry"); - disputeTemplateRegistry = await DisputeTemplateRegistry.deploy(); + await deployments.fixture(["Arbitration", "VeaMock"], { + fallbackToGlobal: true, + keepExistingDeployments: false, + }); + arbitrator = (await ethers.getContract("KlerosCore")) as KlerosCore; + disputeTemplateRegistry = (await ethers.getContract("DisputeTemplateRegistry")) as DisputeTemplateRegistry; + + const court = await arbitrator.courts(1); + await arbitrator.changeCourtParameters( + 1, + court.hiddenVotes, + court.minStake, + court.alpha, + arbitrationFee, + court.jurorsForCourtJump, + [0, 0, 0, appealTimeout] + ); const EvidenceModule = await ethers.getContractFactory("ModeratedEvidenceModule"); evidenceModule = await EvidenceModule.deploy( @@ -84,7 +100,6 @@ describe("Home Evidence contract", async () => { let newArbitratorData = await evidenceModule.arbitratorDataList(lastArbitratorIndex); let oldArbitratorData = await evidenceModule.arbitratorDataList(lastArbitratorIndex.sub(BigNumber.from(1))); - expect(newArbitratorData.disputeTemplateId).to.equal(oldArbitratorData.disputeTemplateId.add(BigNumber.from(1))); expect(newArbitratorData.arbitratorExtraData).to.equal(oldArbitratorData.arbitratorExtraData); const disputeTemplateEvents = await disputeTemplateRegistry.queryFilter( disputeTemplateRegistry.filters.DisputeTemplate(), @@ -250,7 +265,7 @@ describe("Home Evidence contract", async () => { ).args; expect(_arbitrator).to.equal(arbitrator.address, "Wrong arbitrator."); expect(_arbitrableDisputeID).to.equal(0, "Wrong dispute ID."); - expect(_templateId).to.equal(0, "Wrong template ID."); + expect(_templateId).to.equal(1, "Wrong template ID."); expect(_externalDisputeID).to.equal(evidenceID, "Wrong external dispute ID."); await expect( diff --git a/cspell.json b/cspell.json index 3c3c7b792..2862030d1 100644 --- a/cspell.json +++ b/cspell.json @@ -9,6 +9,7 @@ "softwareTerms" ], "words": [ + "Arbitrables", "arbitrum", "ARBMAINNET", "ARBSEPOLIA", diff --git a/eslint-config/package.json b/eslint-config/package.json index 0568485f6..cd5f47ed2 100644 --- a/eslint-config/package.json +++ b/eslint-config/package.json @@ -5,19 +5,22 @@ "main": ".eslintrc.js", "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", - "@typescript-eslint/utils": "^5.62.0", - "eslint-config-prettier": "^8.10.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.29.1", + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1", + "@typescript-eslint/utils": "^8.8.1", + "eslint-config-prettier": "^9.1.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-promise": "^5.2.0", - "eslint-plugin-security": "^1.7.1", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-promise": "^6.0.0", + "eslint-plugin-security": "^3.0.1", "eslint-utils": "^3.0.0" }, "devDependencies": { + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.12.0", + "globals": "^15.11.0", "typescript": "^5.3.3" }, "peerDependencies": { diff --git a/kleros-sdk/src/dataMappings/actions/callAction.ts b/kleros-sdk/src/dataMappings/actions/callAction.ts index 795e8ceca..c949b955e 100644 --- a/kleros-sdk/src/dataMappings/actions/callAction.ts +++ b/kleros-sdk/src/dataMappings/actions/callAction.ts @@ -13,6 +13,7 @@ export const callAction = async (mapping: AbiCallMapping, alchemyApiKey: string) const data = await publicClient.readContract({ address, abi: [parsedAbi], + functionName: "TODO: FIX ME", args, }); diff --git a/kleros-sdk/src/dataMappings/actions/eventAction.ts b/kleros-sdk/src/dataMappings/actions/eventAction.ts index 73895720b..1befb9035 100644 --- a/kleros-sdk/src/dataMappings/actions/eventAction.ts +++ b/kleros-sdk/src/dataMappings/actions/eventAction.ts @@ -1,4 +1,5 @@ import { parseAbiItem } from "viem"; +import { type AbiEvent } from "abitype"; import { AbiEventMapping } from "src/dataMappings/utils/actionTypes"; import { createResultObject } from "src/dataMappings/utils/createResultObject"; import { configureSDK, getPublicClient } from "src/sdk"; @@ -8,17 +9,17 @@ export const eventAction = async (mapping: AbiEventMapping, alchemyApiKey: strin const publicClient = getPublicClient(); const { abi: source, address, eventFilter, seek, populate } = mapping; - const parsedAbi = typeof source === "string" ? parseAbiItem(source) : source; + const parsedAbi = parseAbiItem(source) as AbiEvent; const filter = await publicClient.createEventFilter({ address, event: parsedAbi, args: eventFilter.args, - fromBlock: eventFilter.fromBlock, - toBlock: eventFilter.toBlock, + fromBlock: eventFilter.fromBlock ? BigInt(eventFilter.fromBlock.toString()) : undefined, + toBlock: eventFilter.toBlock ? BigInt(eventFilter.toBlock.toString()) : undefined, }); - const contractEvent = await publicClient.getFilterLogs({ filter: filter as any }); + const contractEvent = await publicClient.getFilterLogs({ filter }); const eventData = contractEvent[0].args; return createResultObject(eventData, seek, populate); diff --git a/kleros-sdk/src/dataMappings/actions/fetchIpfsJsonAction.ts b/kleros-sdk/src/dataMappings/actions/fetchIpfsJsonAction.ts index b8cc5c493..f2ea6f29c 100644 --- a/kleros-sdk/src/dataMappings/actions/fetchIpfsJsonAction.ts +++ b/kleros-sdk/src/dataMappings/actions/fetchIpfsJsonAction.ts @@ -12,15 +12,22 @@ export const fetchIpfsJsonAction = async (mapping: FetchIpfsJsonMapping) => { httpUri = ipfsUri.replace("ipfs://", "https://ipfs.io/ipfs/"); } else if (!ipfsUri.startsWith("http")) { httpUri = `https://ipfs.io/ipfs/${ipfsUri}`; + } else { + throw new Error("Invalid IPFS URI format"); } + const response = await fetch(httpUri, { method: "GET" }); - if (response.headers.get("content-length") > MAX_BYTE_SIZE) { + if (!response.ok) { + throw new Error("Failed to fetch data from IPFS"); + } + + const contentLength = response.headers.get("content-length"); + if (contentLength && parseInt(contentLength) > MAX_BYTE_SIZE) { throw new Error("Response size is too large"); } const contentType = response.headers.get("content-type"); - if (!contentType || !contentType.includes("application/json")) { throw new Error("Fetched data is not JSON"); } diff --git a/kleros-sdk/src/dataMappings/executeActions.ts b/kleros-sdk/src/dataMappings/executeActions.ts index c5b7c8fbc..013e1d5d6 100644 --- a/kleros-sdk/src/dataMappings/executeActions.ts +++ b/kleros-sdk/src/dataMappings/executeActions.ts @@ -14,9 +14,17 @@ import { } from "./utils/actionTypeValidators"; import { ActionMapping } from "./utils/actionTypes"; import { replacePlaceholdersWithValues } from "./utils/replacePlaceholdersWithValues"; +import { Address } from "viem"; -export const executeAction = async (mapping: ActionMapping, context: Record = {}) => { - mapping = replacePlaceholdersWithValues(mapping, context); +// Add these type definitions at the top of the file +type ActionResult = Record | null | undefined; + +// Update the function signature +export const executeAction = async ( + mapping: ActionMapping, + context: Record = {} +): Promise => { + mapping = replacePlaceholdersWithValues(mapping, context) as ActionMapping; switch (mapping.type) { case "graphql": @@ -24,21 +32,24 @@ export const executeAction = async (mapping: ActionMapping, context: Record { - const context = { ...initialContext }; +export const executeActions = async ( + mappings: ActionMapping[], + initialContext: Record = {} +): Promise> => { + const context: Record = { ...initialContext }; for (const mapping of mappings) { const actionResult = await executeAction(mapping, context); diff --git a/kleros-sdk/src/dataMappings/retrieveRealityData.ts b/kleros-sdk/src/dataMappings/retrieveRealityData.ts index d7004693d..be3b377a1 100644 --- a/kleros-sdk/src/dataMappings/retrieveRealityData.ts +++ b/kleros-sdk/src/dataMappings/retrieveRealityData.ts @@ -59,6 +59,10 @@ export const retrieveRealityData = async (realityQuestionID: string, arbitrable? const templateData = await executeAction(templateMapping); console.log("templateData", templateData); + if (!templateData || !questionData) { + throw new Error("Failed to retrieve template or question data"); + } + const rc_question = require("@reality.eth/reality-eth-lib/formatters/question.js"); const populatedTemplate = rc_question.populatedJSONForTemplate( templateData.questionText, @@ -67,7 +71,15 @@ export const retrieveRealityData = async (realityQuestionID: string, arbitrable? console.log("populatedTemplate", populatedTemplate); - let answers = []; + interface RealityAnswer { + title: string; + description: string; + id: string; + reserved: boolean; + last?: boolean; + } + + let answers: RealityAnswer[] = []; if (populatedTemplate.type === "bool") { answers = [ { diff --git a/kleros-sdk/src/dataMappings/utils/actionTypes.ts b/kleros-sdk/src/dataMappings/utils/actionTypes.ts index d8b460113..efc7a2343 100644 --- a/kleros-sdk/src/dataMappings/utils/actionTypes.ts +++ b/kleros-sdk/src/dataMappings/utils/actionTypes.ts @@ -1,3 +1,5 @@ +import { type Address } from "viem"; + export type JsonMapping = { type: string; value: object; @@ -17,7 +19,7 @@ export interface SubgraphMapping { export type AbiCallMapping = { type: string; abi: string; - address: string; + address: Address; args: any[]; seek: string[]; populate: string[]; @@ -26,7 +28,7 @@ export type AbiCallMapping = { export type AbiEventMapping = { type: string; abi: string; - address: string; + address: Address; eventFilter: { fromBlock: BigInt | string; toBlock: BigInt | string; diff --git a/kleros-sdk/src/dataMappings/utils/createResultObject.ts b/kleros-sdk/src/dataMappings/utils/createResultObject.ts index 4c4ed2155..0dd0575ef 100644 --- a/kleros-sdk/src/dataMappings/utils/createResultObject.ts +++ b/kleros-sdk/src/dataMappings/utils/createResultObject.ts @@ -1,5 +1,9 @@ -export const createResultObject = (sourceData, seek: string[], populate: string[]) => { - const result = {}; +export const createResultObject = ( + sourceData: Record, + seek: string[], + populate: string[] +): Record => { + const result: Record = {}; const getNestedValue = (obj: any, path: string) => { return path.split(".").reduce((acc, part) => { diff --git a/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts b/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts index 8d858a8c5..3366cf750 100644 --- a/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts +++ b/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts @@ -2,9 +2,9 @@ import { z } from "zod"; import { isAddress } from "viem"; import { normalize } from "viem/ens"; -const isHexAddress = (str: string): boolean => /^0x[a-fA-F0-9]{40}$/.test(str); -const isHexId = (str: string): boolean => /^0x[a-fA-F0-9]{1,64}$/.test(str); -const isMultiaddr = (str: string): boolean => +export const isHexAddress = (str: string): boolean => /^0x[a-fA-F0-9]{40}$/.test(str); +export const isHexId = (str: string): boolean => /^0x[a-fA-F0-9]{1,64}$/.test(str); +export const isMultiaddr = (str: string): boolean => /^\/(?:ip4|ip6|dns4|dns6|dnsaddr|tcp|udp|utp|tls|ws|wss|p2p-circuit|p2p-webrtc-star|p2p-webrtc-direct|p2p-websocket-star|onion|ipfs)(\/[^\s\/]+)+$|^ipfs:\/\/[a-zA-Z0-9]+\/[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)?$/.test( str ); diff --git a/kleros-sdk/src/dataMappings/utils/replacePlaceholdersWithValues.ts b/kleros-sdk/src/dataMappings/utils/replacePlaceholdersWithValues.ts index 2a54ad231..d628afb7e 100644 --- a/kleros-sdk/src/dataMappings/utils/replacePlaceholdersWithValues.ts +++ b/kleros-sdk/src/dataMappings/utils/replacePlaceholdersWithValues.ts @@ -1,17 +1,23 @@ import mustache from "mustache"; +import { ActionMapping } from "./actionTypes"; -export const replacePlaceholdersWithValues = (mapping: any, context: Record) => { - const replace = (obj) => { +export function replacePlaceholdersWithValues( + mapping: ActionMapping, + context: Record +): ActionMapping | ActionMapping[] { + function replace(obj: ActionMapping): ActionMapping | ActionMapping[] { if (typeof obj === "string") { - return mustache.render(obj, context); + return mustache.render(obj, context) as unknown as ActionMapping; } else if (Array.isArray(obj)) { - return obj.map(replace); + return obj.map(replace) as unknown as ActionMapping[]; } else if (typeof obj === "object" && obj !== null) { - return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, replace(value)])); + return Object.fromEntries( + Object.entries(obj).map(([key, value]) => [key, replace(value)]) + ) as unknown as ActionMapping[]; } else { return obj; } - }; + } return replace(mapping); -}; +} diff --git a/kleros-sdk/src/sdk.ts b/kleros-sdk/src/sdk.ts index 9a9202a3e..bec9ff64c 100644 --- a/kleros-sdk/src/sdk.ts +++ b/kleros-sdk/src/sdk.ts @@ -1,7 +1,7 @@ -import { createPublicClient, webSocket } from "viem"; +import { createPublicClient, webSocket, type PublicClient } from "viem"; import { arbitrumSepolia } from "viem/chains"; -let publicClient; +let publicClient: PublicClient | undefined; export const configureSDK = (config: { apiKey?: string }) => { if (config.apiKey) { @@ -14,7 +14,7 @@ export const configureSDK = (config: { apiKey?: string }) => { } }; -export const getPublicClient = () => { +export const getPublicClient = (): PublicClient => { if (!publicClient) { throw new Error("SDK not configured. Please call `configureSDK` before using."); } diff --git a/package.json b/package.json index 070afc820..27536919b 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,15 @@ "kleros-sdk", "subgraph", "web", + "web-devtools", "eslint-config", "prettier-config", "tsconfig" ], "packageManager": "yarn@4.0.2+sha256.825003a0f561ad09a3b1ac4a3b3ea6207af2796d54f62a9420520915721f5186", "volta": { - "node": "20.11.0" + "node": "20.11.0", + "yarn": "4.3.1" }, "devDependencies": { "@commitlint/cli": "^17.8.1", diff --git a/prettier-config/package.json b/prettier-config/package.json index 23c0e2e12..b237e8474 100644 --- a/prettier-config/package.json +++ b/prettier-config/package.json @@ -4,7 +4,7 @@ "main": "index.js", "license": "MIT", "dependencies": { - "eslint": "^8.56.0", + "eslint": "^8.57.1", "prettier": "^2.8.8", "prettier-plugin-solidity": "^1.3.1" }, diff --git a/web-devtools/.editorconfig b/web-devtools/.editorconfig new file mode 100644 index 000000000..332275afb --- /dev/null +++ b/web-devtools/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +charset = utf-8 + +[*.{html,js,.json,mjs,rjson,ts}] +indent_style = space +indent_size = 2 + +[*.sol] +indent_style = space +indent_size = 4 diff --git a/web-devtools/.env.local.example b/web-devtools/.env.local.example new file mode 100644 index 000000000..acab203c2 --- /dev/null +++ b/web-devtools/.env.local.example @@ -0,0 +1,6 @@ +# Do not enter sensitive information here. +export NEXT_PUBLIC_ALCHEMY_API_KEY= +export NEXT_PUBLIC_DEPLOYMENT=devnet +export NEXT_PUBLIC_CORE_SUBGRAPH=https://api.studio.thegraph.com/query/61738/kleros-v2-core-devnet/version/latest +export NEXT_PUBLIC_DRT_ARBSEPOLIA_SUBGRAPH=https://api.studio.thegraph.com/query/61738/kleros-v2-drt-arbisep-devnet/version/latest +export NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID= \ No newline at end of file diff --git a/web-devtools/.gitignore b/web-devtools/.gitignore new file mode 100644 index 000000000..e8878e264 --- /dev/null +++ b/web-devtools/.gitignore @@ -0,0 +1,46 @@ +# dependencies +/.yarn/* +!/.yarn/versions +!/.yarn/plugins +!/.yarn/releases +!/.yarn/sdks +/.pnp.* +node_modules + +# next.js +/.next/ +/out/ +development +build +dist + +# misc +*.pem +.eslintcache +.DS_Store +.env +.env.test +.env.testnet +.env.devnet +.env.local +.env.development.local +.env.test.local +.env.production.local + +# generated code +src/hooks/contracts/generated.ts +src/graphql-generated +generatedGitInfo.json +generatedNetlifyInfo.json + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# testing +/coverage + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/web-devtools/LICENSE b/web-devtools/LICENSE new file mode 100644 index 000000000..469d9f99c --- /dev/null +++ b/web-devtools/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Kleros + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/web-devtools/README.md b/web-devtools/README.md new file mode 100644 index 000000000..ef1660604 --- /dev/null +++ b/web-devtools/README.md @@ -0,0 +1,3 @@ +# Dev Tools Frontend + +In construction diff --git a/web-devtools/codegen.ts b/web-devtools/codegen.ts new file mode 100644 index 000000000..48a5af00c --- /dev/null +++ b/web-devtools/codegen.ts @@ -0,0 +1,16 @@ +import type { CodegenConfig } from "@graphql-codegen/cli"; + +import { getGraphqlUrl } from "./src/utils/getGraphqlUrl"; + +const config: CodegenConfig = { + overwrite: true, + schema: [getGraphqlUrl(false), getGraphqlUrl(true)], + documents: "./src/hooks/queries/*.ts", + generates: { + "./src/graphql-generated/": { + preset: "client", + }, + }, +}; + +export default config; diff --git a/web-devtools/eslint.config.mjs b/web-devtools/eslint.config.mjs new file mode 100644 index 000000000..7a660d131 --- /dev/null +++ b/web-devtools/eslint.config.mjs @@ -0,0 +1,186 @@ +import { fixupConfigRules, fixupPluginRules } from "@eslint/compat"; +import react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; +import security from "eslint-plugin-security"; +import _import from "eslint-plugin-import"; +import globals from "globals"; +import tsParser from "@typescript-eslint/parser"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default [ + { + ignores: ["src/assets", "src/hooks/contracts/generated.ts", "src/graphql-generated/**/*.ts"], + }, + ...fixupConfigRules( + compat.extends( + "next/core-web-vitals", + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:import/recommended", + "plugin:import/react", + "plugin:security/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "prettier" + ) + ), + { + plugins: { + react: fixupPluginRules(react), + "react-hooks": fixupPluginRules(reactHooks), + security: fixupPluginRules(security), + import: fixupPluginRules(_import), + }, + + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + Atomics: "readonly", + SharedArrayBuffer: "readonly", + }, + + parser: tsParser, + ecmaVersion: 2020, + sourceType: "module", + + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + + settings: { + react: { + version: "^16.12.0", + }, + + "import/resolver": { + typescript: { + alwaysTryTypes: true, + project: "./tsconfig.json", + }, + + node: { + extensions: [".js", ".jsx", ".ts", ".tsx"], + }, + }, + }, + + rules: { + "max-len": [ + "warn", + { + code: 120, + }, + ], + + "react/prop-types": 0, + "no-unused-vars": "off", + + "@typescript-eslint/no-unused-vars": [ + "error", + { + varsIgnorePattern: "(^_+[0-9]*$)|([iI]gnored$)|(^ignored)", + argsIgnorePattern: "(^_+[0-9]*$)|([iI]gnored$)|(^ignored)", + }, + ], + + "no-console": [ + "error", + { + allow: ["warn", "error", "info", "debug"], + }, + ], + + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-explicit-any": "off", + "security/detect-object-injection": "off", + "security/detect-non-literal-fs-filename": "off", + + "import/extensions": [ + "error", + "ignorePackages", + { + js: "never", + jsx: "never", + ts: "never", + tsx: "never", + }, + ], + + "import/no-unresolved": "off", + + "import/order": [ + "warn", + { + groups: ["builtin", "external", "internal", "parent", "sibling", "index"], + + pathGroups: [ + { + pattern: "{react,styled-components}", + group: "external", + position: "before", + }, + { + pattern: "@kleros/**", + group: "external", + position: "after", + }, + { + pattern: "{svgs/**,assets/**}", + group: "internal", + position: "after", + }, + { + pattern: "{hooks/**,utils/**,consts/**,types/**,context/**,connectors/**,}", + group: "internal", + position: "after", + }, + { + pattern: "{queries/**,}", + group: "internal", + position: "after", + }, + { + pattern: "{src/**,}", + group: "internal", + position: "after", + }, + { + pattern: "{styles/**,}", + group: "internal", + position: "after", + }, + { + pattern: "{layout/**,pages/**,components/**,}", + group: "internal", + position: "after", + }, + ], + + pathGroupsExcludedImportTypes: ["builtin"], + "newlines-between": "always", + + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + }, + ], + }, + }, +]; diff --git a/web-devtools/global.d.ts b/web-devtools/global.d.ts new file mode 100644 index 000000000..09cc2ad78 --- /dev/null +++ b/web-devtools/global.d.ts @@ -0,0 +1,6 @@ +import { DefaultTheme } from "styled-components"; +import { theme } from "styles/Theme"; +declare module "styled-components" { + type Theme = typeof theme; + export interface DefaultTheme extends Theme {} +} diff --git a/web-devtools/netlify.toml b/web-devtools/netlify.toml new file mode 100644 index 000000000..d12df6eae --- /dev/null +++ b/web-devtools/netlify.toml @@ -0,0 +1,14 @@ +## Yarn 3 cache does not work out of the box as of Jan 2022. Context: +## https://github.com/netlify/build/issues/1535#issuecomment-1021947989 +[build.environment] +NETLIFY_USE_YARN = "true" +NETLIFY_YARN_WORKSPACES = "true" +YARN_ENABLE_GLOBAL_CACHE = "true" +# YARN_CACHE_FOLDER = "$HOME/.yarn_cache" +# YARN_VERSION = "3.2.0" + +[functions] +directory = "web-devtools/netlify/functions/" + +[dev] +framework = "nextjs" \ No newline at end of file diff --git a/web-devtools/next.config.mjs b/web-devtools/next.config.mjs new file mode 100644 index 000000000..576875c28 --- /dev/null +++ b/web-devtools/next.config.mjs @@ -0,0 +1,43 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + compiler: { + styledComponents: true, + }, + typescript: { + // !! WARN !! + // Dangerously allow production builds to successfully complete even if + // your project has type errors. + // !! WARN !! + // ignoreBuildErrors: true, + }, + webpack(config) { + // Grab the existing rule that handles SVG imports + const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.(".svg")); + if (!fileLoaderRule) { + throw new Error("Could not find the existing SVG rule to modify."); + } + + config.module.rules.push( + // Reapply the existing rule, but only for svg imports ending in ?url + { + ...fileLoaderRule, + test: /\.svg$/i, + resourceQuery: /url/, // *.svg?url + }, + // Convert all other *.svg imports to React components + { + test: /\.svg$/i, + issuer: fileLoaderRule.issuer, + resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] }, // exclude if *.svg?url + use: ["@svgr/webpack"], + } + ); + + // Modify the file loader rule to ignore *.svg, since we have it handled now. + fileLoaderRule.exclude = /\.svg$/i; + + return config; + }, +}; + +export default nextConfig; diff --git a/web-devtools/package.json b/web-devtools/package.json new file mode 100644 index 000000000..ff94096c7 --- /dev/null +++ b/web-devtools/package.json @@ -0,0 +1,64 @@ +{ + "name": "@kleros/kleros-v2-web-devtools", + "version": "0.1.0", + "source": "src/index.html", + "browserslist": "> 0.5%, not dead", + "repository": "", + "author": "", + "license": "MIT", + "type": "module", + "packageManager": "yarn@4.0.2+sha256.825003a0f561ad09a3b1ac4a3b3ea6207af2796d54f62a9420520915721f5186", + "volta": { + "node": "20.11.0", + "yarn": "4.3.1" + }, + "scripts": { + "clean": "rimraf .next src/graphql-generated src/hooks/contracts/generated.ts", + "dev": "scripts/runEnv.sh local 'yarn generate && next dev'", + "start": "scripts/runEnv.sh local 'yarn generate && next start'", + "build": "scripts/runEnv.sh local 'yarn generate && next build'", + "build-netlify": "yarn generate && next build", + "lint": "next lint", + "generate": "yarn generate:gql && yarn generate:hooks", + "generate:gql": "graphql-codegen", + "generate:hooks": "NODE_NO_WARNINGS=1 wagmi generate" + }, + "prettier": "@kleros/kleros-v2-prettier-config", + "devDependencies": { + "@graphql-codegen/cli": "^5.0.2", + "@graphql-codegen/client-preset": "^4.3.2", + "@svgr/webpack": "^8.1.0", + "@types/node": "^20", + "@types/react": "18.2.0", + "@types/react-dom": "^18.2.18", + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1", + "@typescript-eslint/utils": "^8.8.1", + "@wagmi/cli": "^2.0.3", + "eslint": "^8.57.1", + "eslint-config-next": "^14.2.15", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-react": "^7.37.1", + "eslint-plugin-react-hooks": "^4.6.2", + "rimraf": "^6.0.1", + "ts-node": "^10.9.2", + "typescript": "^5.5.3" + }, + "dependencies": { + "@kleros/kleros-sdk": "workspace:^", + "@kleros/ui-components-library": "^2.15.0", + "@web3modal/wagmi": "^5.1.11", + "graphql": "^16.8.1", + "graphql-request": "^7.1.0", + "next": "14.2.14", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-markdown": "^8.0.7", + "react-toastify": "^10.0.5", + "typewriter-effect": "^2.21.0", + "vanilla-jsoneditor": "^0.21.4", + "viem": "^2.1.0", + "wagmi": "^2.2.1" + } +} diff --git a/web-devtools/scripts/runEnv.sh b/web-devtools/scripts/runEnv.sh new file mode 100755 index 000000000..acbc1fe3c --- /dev/null +++ b/web-devtools/scripts/runEnv.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +deployment="$1" +shift +commands="$*" + +if [[ -z "$deployment" ]]; then + echo "usage: $(basename "$0") " + exit 1 +fi + +valid_deployments=("local" "devnet" "devnet-neo" "devnet-university" "testnet" "mainnet-neo") +if [[ ! " ${valid_deployments[*]} " =~ ${deployment} ]]; then + echo "Invalid deployment option. Please choose either: ${valid_deployments[*]}." + exit 1 +fi + +function sourceEnvFile() { #envFile + envFile="$1" + if [ -f "$envFile" ]; then + echo -e "${GREEN}✔${NC} $(basename "$envFile")" + # shellcheck source=SCRIPTDIR/../.env.devnet + . "$envFile" + else + echo -e "${RED}✖${NC} $(basename "$envFile")" + fi +} + +envFile="$SCRIPT_DIR/../.env.${deployment}" +sourceEnvFile "$envFile" +sourceEnvFile "$envFile.public" + +eval "$commands" diff --git a/web-devtools/src/app/(main)/(homepage)/Header.tsx b/web-devtools/src/app/(main)/(homepage)/Header.tsx new file mode 100644 index 000000000..d2e9a21d6 --- /dev/null +++ b/web-devtools/src/app/(main)/(homepage)/Header.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import styled from "styled-components"; + +import Typewriter from "typewriter-effect"; + +import { responsiveSize } from "styles/responsiveSize"; + +const StyledHeader = styled.div` + display: flex; + justify-content: space-between; +`; + +const StyledH1 = styled.h1` + display: flex; + gap: 8px; + font-size: ${responsiveSize(21, 24)}; + font-weight: 500; + margin-bottom: 48px; + letter-spacing: 1px; +`; + +const TypewriterContainer = styled.div` + .typewriter-text { + color: ${({ theme }) => theme.klerosUIComponentsSecondaryPurple}; + } +`; + +const Header: React.FC = () => { + const Phrases = ["Manage Courts", "Get Insights", "Edit Dispute Templates", "Get PNK Faucets", "Boost productivity"]; + + return ( + + + Developer Toolkit: + + + + + + ); +}; + +export default Header; diff --git a/web-devtools/src/app/(main)/(homepage)/Tools.tsx b/web-devtools/src/app/(main)/(homepage)/Tools.tsx new file mode 100644 index 000000000..f656fff4b --- /dev/null +++ b/web-devtools/src/app/(main)/(homepage)/Tools.tsx @@ -0,0 +1,95 @@ +import React from "react"; +import styled from "styled-components"; + +import Link from "next/link"; + +import PaperIcon from "svgs/icons/arrow.svg"; + +const Container = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + border-top: 3px solid ${({ theme }) => theme.klerosUIComponentsSecondaryPurple}; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + background-color: ${({ theme }) => theme.klerosUIComponentsWhiteBackground}; + padding: 16px; +`; + +const ToolList = styled.div` + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; + width: 100%; + @media (max-width: 768px) { + grid-template-columns: 1fr; + } +`; + +const ToolItem = styled.li` + display: flex; + align-items: center; + gap: 8px; + padding: 16px 16px; + border: 1px solid ${({ theme }) => theme.klerosUIComponentsLightBlue}; + border-radius: 3px; + background-color: ${({ theme }) => theme.klerosUIComponentsLightBackground}; + width: 100%; + transition: background-color 0.3s; +`; + +const ToolLink = styled.div` + display: flex; + align-items: center; + text-decoration: none; + gap: 8px; + color: ${({ theme }) => theme.klerosUIComponentsSecondaryText}; + width: 100%; +`; + +const SVGContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + svg { + fill: ${({ theme }) => theme.klerosUIComponentsSecondaryPurple}; + height: 12px; + width: 12px; + } +`; + +const ToolName = styled.span` + font-size: 16px; +`; + +const tools = [ + { name: "Dispute Templates Preview", route: "/dispute-template" }, + { name: "Configure Ruler", route: "/ruler" }, + { name: "Courts Manager (coming soon)", route: "/" }, + { name: "Arbitrable Explorer (coming soon)", route: "/" }, +]; + +const Tools: React.FC = () => { + return ( + +

Tools

+ + {tools.map((tool, index) => ( + + + + + + + {tool.name} + + + + ))} + +
+ ); +}; + +export default Tools; diff --git a/web-devtools/src/app/(main)/(homepage)/page.tsx b/web-devtools/src/app/(main)/(homepage)/page.tsx new file mode 100644 index 000000000..1d4395dca --- /dev/null +++ b/web-devtools/src/app/(main)/(homepage)/page.tsx @@ -0,0 +1,32 @@ +"use client"; +import React from "react"; +import styled from "styled-components"; + +import { responsiveSize } from "styles/responsiveSize"; + +import HeroImage from "components/HeroImage"; + +import Header from "./Header"; +import Tools from "./Tools"; + +const Container = styled.div` + width: 100%; + background-color: ${({ theme }) => theme.klerosUIComponentsLightBackground}; + padding: ${responsiveSize(32, 72)} ${responsiveSize(24, 132)} ${responsiveSize(76, 96)}; + max-width: 1780px; + margin: 0 auto; +`; + +const Home: React.FC = () => { + return ( +
+ + +
+ + +
+ ); +}; + +export default Home; diff --git a/web-devtools/src/app/(main)/dispute-template/FetchDisputeRequestInput.tsx b/web-devtools/src/app/(main)/dispute-template/FetchDisputeRequestInput.tsx new file mode 100644 index 000000000..3347ca670 --- /dev/null +++ b/web-devtools/src/app/(main)/dispute-template/FetchDisputeRequestInput.tsx @@ -0,0 +1,139 @@ +import React, { useEffect, useState } from "react"; +import styled from "styled-components"; + +import { useDebounce } from "react-use"; +import { GetEventArgs } from "viem"; + +import { Field } from "@kleros/ui-components-library"; + +import { DEFAULT_CHAIN } from "consts/chains"; +import { iArbitrableV2Abi } from "hooks/contracts/generated"; +import { getDisputeRequestParamsFromTxn } from "utils/getDisputeRequestParamsFromTxn"; +import { isUndefined } from "utils/isUndefined"; + +const Container = styled.div` + display: flex; + flex-direction: column; + margin-top: 24px; + margin-left: 24px; +`; +const InputContainer = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; +`; +const StyledChainInput = styled(Field)` + width: 120px; +`; +const StyledHeader = styled.h2` + margin-top: 24px; +`; + +const StyledH3 = styled.h3` + margin-top: 28px; +`; + +const PresetsContainer = styled.div` + display: flex; + gap: 16px; + flex-wrap: wrap; +`; + +const StyledA = styled.a` + cursor: pointer; +`; + +const presets = [ + { + title: "Escrow", + txnHash: "0x85e60cb407c9a38e625263cc762ff4283d01f38201825e1d20109d8664cfa7d4", + chainId: 421614, + }, + { + title: "Curated Lists", + txnHash: "0x6e5ad6f7436ef8570b50b0fbec76a11ccedbed85030c670e59d8f6617a499108", + chainId: 421614, + }, + { + title: "Trump-Biden", + txnHash: "0x9a3a420174f3c55c2b3eb2e77266777b74028b845e528a90142b5b57aafbdb90", + chainId: 421614, + }, +]; + +export type DisputeRequest = GetEventArgs & { + _arbitrable: `0x${string}`; +}; + +interface IFetchDisputeRequestInput { + setParams: (params: DisputeRequest) => void; +} + +const FetchDisputeRequestInput: React.FC = ({ setParams }) => { + const [chainId, setChainId] = useState(DEFAULT_CHAIN); + const [txnHash, setTxnHash] = useState(""); + const [debouncedTxnHash, setDebouncedTxnHash] = useState(""); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + useDebounce( + () => { + setDebouncedTxnHash(txnHash); + }, + 1000, + [txnHash] + ); + + useEffect(() => { + const fetchData = async () => { + setLoading(true); + try { + const params = await getDisputeRequestParamsFromTxn(debouncedTxnHash as `0x${string}`, chainId); + if (!isUndefined(params)) setParams(params); + setError(null); + } catch (error) { + console.error("Error fetching dispute request params:", error); + setError("Failed to fetch dispute request parameters"); + } finally { + setLoading(false); + } + }; + if (debouncedTxnHash && chainId) fetchData(); + }, [debouncedTxnHash, chainId]); + + return ( + + Fetch Dispute Request params from transaction + + setTxnHash(e.target.value)} + message={loading ? "fetching ..." : error || ""} + /> + setChainId(Number(e.target.value))} + /> + + Presets + + {presets.map((preset) => ( + { + setTxnHash(preset.txnHash); + setChainId(preset.chainId); + }} + > + {preset.title} + + ))} + + + ); +}; + +export default FetchDisputeRequestInput; diff --git a/web-devtools/src/app/(main)/dispute-template/FetchFromIdInput.tsx b/web-devtools/src/app/(main)/dispute-template/FetchFromIdInput.tsx new file mode 100644 index 000000000..c154e41ad --- /dev/null +++ b/web-devtools/src/app/(main)/dispute-template/FetchFromIdInput.tsx @@ -0,0 +1,76 @@ +import React, { useEffect, useState } from "react"; +import styled from "styled-components"; + +import { useDebounce } from "react-use"; + +import { Field } from "@kleros/ui-components-library"; + +import { useDisputeTemplateFromId } from "hooks/queries/useDisputeTemplateFromId"; +import { isUndefined } from "utils/isUndefined"; + +const Container = styled.div` + display: flex; + flex-direction: column; + margin-top: 24px; + margin-left: 24px; +`; + +const StyledInput = styled(Field)``; +const StyledHeader = styled.h2` + margin-top: 24px; +`; + +interface IFetchFromID { + setDisputeTemplateInput: (templateData: string) => void; + setDataMappingsInput: (dataMappings: string) => void; + defaultTemplateID: string; +} + +const FetchFromIDInput: React.FC = ({ + setDisputeTemplateInput, + setDataMappingsInput, + defaultTemplateID = "", +}) => { + const [templateId, setTemplateId] = useState(""); + const [debouncedTemplateId, setDebouncedTemplateId] = useState(""); + useDebounce( + () => { + setDebouncedTemplateId(templateId); + }, + 1000, + [templateId] + ); + useEffect(() => setTemplateId(defaultTemplateID), [defaultTemplateID]); + const { data: templateFromId, isLoading, error } = useDisputeTemplateFromId(debouncedTemplateId); + + useEffect(() => { + const templateData = templateFromId?.disputeTemplate?.templateData; + const templateDataMappings = templateFromId?.disputeTemplate?.templateDataMappings; + if (!isUndefined(templateData)) setDisputeTemplateInput(tryPrettify(templateData)); + if (!isUndefined(templateDataMappings)) setDataMappingsInput(tryPrettify(templateDataMappings)); + if (error) { + console.error("Error fetching template:", error); + } + }, [templateFromId, error]); + + return ( + + Fetch dispute template from template ID + setTemplateId(e.target.value)} + /> + + ); +}; +// will try to format else will be repaired in editor +const tryPrettify = (text: string) => { + try { + return JSON.stringify(JSON.parse(text), null, 2); + } catch { + return text; + } +}; +export default FetchFromIDInput; diff --git a/web-devtools/src/app/(main)/dispute-template/page.tsx b/web-devtools/src/app/(main)/dispute-template/page.tsx new file mode 100644 index 000000000..c8f5acdb0 --- /dev/null +++ b/web-devtools/src/app/(main)/dispute-template/page.tsx @@ -0,0 +1,362 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import styled, { css } from "styled-components"; + +import Skeleton from "react-loading-skeleton"; +import { useDebounce } from "react-use"; +import { Mode } from "vanilla-jsoneditor"; + +import { executeActions } from "@kleros/kleros-sdk/src/dataMappings/executeActions"; +import { Answer, DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes"; +import { populateTemplate } from "@kleros/kleros-sdk/src/dataMappings/utils/populateTemplate"; +import { Field } from "@kleros/ui-components-library"; + +import PolicyIcon from "svgs/icons/policy.svg"; + +import { DEFAULT_CHAIN } from "consts/chains"; +import { INVALID_DISPUTE_DATA_ERROR } from "consts/index"; +import { klerosCoreConfig } from "hooks/contracts/generated"; +import { getIpfsUrl } from "utils/getIpfsUrl"; + +import { landscapeStyle } from "styles/landscapeStyle"; + +import JSONEditor from "components/JSONEditor"; +import ReactMarkdown from "components/ReactMarkdown"; + +import FetchDisputeRequestInput, { DisputeRequest } from "./FetchDisputeRequestInput"; +import FetchFromIDInput from "./FetchFromIdInput"; + +const Container = styled.div` + height: auto; + display: flex; + flex-direction: column; + gap: 16px; + + > h1 { + margin: 0; + } + + > hr { + width: 100%; + } +`; + +const QuestionAndDescription = styled.div` + display: flex; + flex-direction: column; + > * { + margin: 0px; + } +`; + +const VotingOptions = styled(QuestionAndDescription)` + display: flex; + flex-direction: column; + > span { + margin: 0px; + display: flex; + gap: 8px; + } +`; + +const ShadeArea = styled.div` + width: 100%; + padding: 16px; + margin-top: 16px; + background-color: ${({ theme }) => theme.klerosUIComponentsMediumBlue}; + > p { + margin-top: 0; + } +`; + +const StyledA = styled.a` + display: flex; + align-items: center; + gap: 4px; + > svg { + width: 16px; + fill: ${({ theme }) => theme.klerosUIComponentsPrimaryBlue}; + } +`; + +const LinkContainer = styled.div` + display: flex; + justify-content: space-between; +`; + +const LongTextSections = styled.div` + min-height: calc(100vh - 144px); + margin: 24px; + display: flex; + gap: 12px; + flex-direction: column; + ${landscapeStyle( + () => css` + flex-direction: row; + ` + )} +`; +const UpperContainer = styled.div` + display: grid; + grid-template-columns: 1fr; + ${landscapeStyle( + () => css` + grid-template-columns: 1fr 1fr; + ` + )} +`; +const StyledForm = styled.form` + display: flex; + flex-direction: column; + justify-content: center; + margin-top: 24px; + margin-left: 24px; +`; + +const StyledRow = styled.div` + display: flex; + flex-direction: column; + ${landscapeStyle( + () => css` + flex-direction: row; + gap: 24px; + ` + )} +`; + +const StyledP = styled.p` + font-family: "Roboto Mono", monospace; +`; + +const StyledHeader = styled.h2` + margin-top: 24px; +`; + +const StyledTitle = styled.div` + margin-top: 16px; + display: flex; + justify-content: center; + align-items: center; +`; + +const LongText = styled.div` + display: flex; + flex-direction: column; + width: auto; +`; + +const DisputeTemplateView = () => { + const klerosCoreAddress = klerosCoreConfig.address[DEFAULT_CHAIN as keyof typeof klerosCoreConfig.address]; + const [disputeDetails, setDisputeDetails] = useState(undefined); + const [disputeTemplateInput, setDisputeTemplateInput] = useState(""); + const [dataMappingsInput, setDataMappingsInput] = useState(""); + + const [params, setParams] = useState({ + _arbitrable: "0x10f7A6f42Af606553883415bc8862643A6e63fdA", + _arbitrator: klerosCoreAddress as `0x${string}`, + }); + const [debouncedParams, setDebouncedParams] = useState(params); + const [loading, setLoading] = useState(false); + + useDebounce(() => setDebouncedParams(params), 350, [params]); + + const handleFormUpdate = (event: React.ChangeEvent) => { + const value = ["_arbitrator", "_arbitrable", "_templateUri"].includes(event.target.name) + ? event.target.value + : BigInt(event.target.value); + + setParams({ ...params, [event.target.name]: value }); + }; + + useEffect(() => { + let isFetchDataScheduled = false; + + const scheduleFetchData = () => { + if (!isFetchDataScheduled) { + isFetchDataScheduled = true; + + setLoading(true); + + setTimeout(() => { + const initialContext = { + arbitrator: debouncedParams._arbitrator, + arbitrable: debouncedParams._arbitrable, + arbitrableDisputeID: debouncedParams._arbitrableDisputeID, + externalDisputeID: debouncedParams._externalDisputeID, + templateID: debouncedParams._templateId, + templateUri: debouncedParams._templateUri, + }; + + const fetchData = async () => { + try { + const data = dataMappingsInput ? await executeActions(JSON.parse(dataMappingsInput), initialContext) : {}; + const finalDisputeDetails = populateTemplate(disputeTemplateInput, data); + setDisputeDetails(finalDisputeDetails); + } catch (e) { + console.error(e); + setDisputeDetails(undefined); + } finally { + setLoading(false); + } + }; + + fetchData(); + + isFetchDataScheduled = false; + }, 350); + } + }; + + if (disputeTemplateInput || dataMappingsInput || debouncedParams) { + scheduleFetchData(); + } + }, [disputeTemplateInput, dataMappingsInput, debouncedParams]); + + return ( + <> + +

Dispute Preview

+
+ + + Dispute Request event parameters + + {"arbitrator :"} + + + + {"arbitrable :"} + + + + {"arbitrableDisputeID :"} + + + + {"externalDisputeID :"} + + + + {"templateID :"} + + + + {"templateUri :"} + + + +
+ + +
+
+ + + + Template + { + setDisputeTemplateInput(val.text); + }} + /> + + + Data Mapping + { + setDataMappingsInput(val.text); + }} + /> + + + Dispute Preview +
+ {loading ? : } +
+
+ + ); +}; + +const Overview: React.FC<{ disputeDetails: DisputeDetails | undefined }> = ({ disputeDetails }) => { + return ( + +

{disputeDetails?.title ?? INVALID_DISPUTE_DATA_ERROR}

+ + {disputeDetails?.question ?? INVALID_DISPUTE_DATA_ERROR} + {disputeDetails?.description ?? INVALID_DISPUTE_DATA_ERROR} + + {disputeDetails?.frontendUrl && ( + + Go to arbitrable + + )} + + {disputeDetails &&

Voting Options

} + {disputeDetails?.answers?.map((answer: Answer, i: number) => ( + + Option {i + 1}: + + + + ))} +
+ +

Make sure you read and understand the Policies

+ + {disputeDetails?.policyURI && ( + + + Dispute Policy + + )} + +
+
+ ); +}; + +export default DisputeTemplateView; diff --git a/web-devtools/src/app/(main)/layout.tsx b/web-devtools/src/app/(main)/layout.tsx new file mode 100644 index 000000000..3d754b11f --- /dev/null +++ b/web-devtools/src/app/(main)/layout.tsx @@ -0,0 +1,37 @@ +"use client"; +import React from "react"; +import styled from "styled-components"; + +import "react-toastify/dist/ReactToastify.css"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ToastContainer } from "react-toastify"; + +import GraphqlBatcherProvider from "context/GraphqlBatcher"; +import Web3Provider from "context/Web3Provider"; + +const Main = styled.main` + min-height: calc(100vh - 130px); +`; +const queryClient = new QueryClient(); + +const StyledToastContainer = styled(ToastContainer)` + padding: 16px; + padding-top: 70px; +`; + +const Layout = ({ children }: Readonly<{ children: React.ReactNode }>) => { + return ( + + + +
+ + {children} +
+
+
+
+ ); +}; + +export default Layout; diff --git a/web-devtools/src/app/(main)/ruler/ChangeDeveloper.tsx b/web-devtools/src/app/(main)/ruler/ChangeDeveloper.tsx new file mode 100644 index 000000000..4fffe8847 --- /dev/null +++ b/web-devtools/src/app/(main)/ruler/ChangeDeveloper.tsx @@ -0,0 +1,96 @@ +import React, { useCallback, useMemo, useState } from "react"; +import styled from "styled-components"; + +import { Address, isAddress } from "viem"; +import { useAccount, usePublicClient } from "wagmi"; + +import { Button } from "@kleros/ui-components-library"; + +import { useRulerContext } from "context/RulerContext"; +import { useSimulateKlerosCoreRulerChangeRuler, useWriteKlerosCoreRulerChangeRuler } from "hooks/contracts/generated"; +import { isUndefined } from "utils/isUndefined"; +import { wrapWithToast } from "utils/wrapWithToast"; + +import LabeledInput from "components/LabeledInput"; + +import Header from "./Header"; +import { DEFAULT_CHAIN } from "consts/chains"; + +const Container = styled.div` + width: 100%; + display: flex; + flex-direction: column; + gap: 32px; +`; + +const InputContainer = styled.div` + display: flex; + flex-direction: column; + gap: 16px; +`; + +const StyledLabel = styled.label` + word-wrap: break-word; +`; + +const ChangeDeveloper: React.FC = () => { + const { isConnected, chainId } = useAccount(); + const { arbitrable, currentDeveloper, refetchData } = useRulerContext(); + const [newDeveloper, setNewDeveloper] = useState(""); + const [isChanging, setIsChanging] = useState(false); + const publicClient = usePublicClient(); + + const isValid = useMemo(() => newDeveloper === "" || isAddress(newDeveloper), [newDeveloper]); + + const { + data: changeRulerConfig, + isLoading, + isError, + } = useSimulateKlerosCoreRulerChangeRuler({ + query: { + enabled: + !isUndefined(arbitrable) && !isUndefined(newDeveloper) && isAddress(arbitrable) && isAddress(newDeveloper), + }, + args: [arbitrable as Address, newDeveloper as Address], + }); + + const { writeContractAsync: changeRuler } = useWriteKlerosCoreRulerChangeRuler(); + + const handleClick = useCallback(() => { + if (!publicClient || !changeRulerConfig) return; + setIsChanging(true); + wrapWithToast(async () => changeRuler(changeRulerConfig.request), publicClient) + .then(() => refetchData()) + .finally(() => setIsChanging(false)); + }, [publicClient, changeRulerConfig, changeRuler, refetchData]); + + const isDisabled = useMemo( + () => + !isConnected || + chainId !== DEFAULT_CHAIN || + !changeRulerConfig || + isError || + isLoading || + isChanging || + isUndefined(arbitrable) || + !isValid, + [changeRulerConfig, isError, isLoading, isChanging, arbitrable, isValid, isConnected, chainId] + ); + return ( + +
+ + Current Developer : {currentDeveloper ?? "None"} + setNewDeveloper(e.target.value)} + message={isValid ? "" : "Invalid Address"} + variant={isValid ? "" : "error"} + /> + +