├── .env.example ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .lintstagedrc.json ├── .prettierrc.json ├── .solhint.json ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── contracts ├── BatchWithdraw.sol ├── GTCRFactory.sol ├── GeneralizedTCR.sol ├── LightBatchWithdraw.sol ├── LightGTCRFactory.sol ├── LightGeneralizedTCR.sol ├── test-purposes │ ├── AppealableArbitrator.sol │ ├── CentralizedArbitrator.sol │ ├── EnhancedAppealableArbitrator.sol │ └── RelayMock.sol ├── utils │ ├── CappedMath.sol │ └── CappedMath128.sol └── view │ ├── GeneralizedTCRView.sol │ └── LightGeneralizedTCRView.sol ├── deploy └── deploy.js ├── deployments ├── goerli │ └── .chainId ├── mainnet │ ├── .chainId │ ├── BatchWithdraw.json │ ├── GeneralizedTCR.json │ ├── GeneralizedTCRView.json │ └── LightGeneralizedTCRView.json └── mumbai │ ├── .chainId │ └── EnhancedAppealableArbitrator.json ├── hardhat.config.js ├── package.json ├── test ├── gtcr.js ├── light-gtcr-factory.js └── light-gtcr.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | #for deployment 2 | PRIVATE_KEY_GOVERNOR=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 3 | PRIVATE_KEY_REQUESTER=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 4 | 5 | #for deployment + testing add these keys as well 6 | PRIVATE_KEY_CHALLENGER=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 7 | PRIVATE_KEY_GOVERNOR2=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 8 | PRIVATE_KEY_OTHER=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 9 | PRIVATE_KEY_DEPLOYER=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 10 | 11 | #for verification of contracts 12 | ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 13 | INFURA_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 14 | 15 | #For polygon add 16 | POLYGONSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | artifacts/ 2 | cache/ 3 | dist/ 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 2020 4 | }, 5 | "env": { 6 | "browser": true, 7 | "es6": true, 8 | "node": true, 9 | "mocha": true, 10 | "es2020": true 11 | }, 12 | "globals": { 13 | "artifacts": "readonly", 14 | "contract": "readonly", 15 | "assert": "readonly" 16 | }, 17 | "extends": [ 18 | "eslint:recommended", 19 | "plugin:prettier/recommended", 20 | "plugin:import/recommended" 21 | ], 22 | "plugins": [ 23 | "prettier", 24 | "import" 25 | ], 26 | "rules": { 27 | "no-unused-vars": [ 28 | "error", 29 | { 30 | "varsIgnorePattern": "(^_+[0-9]*$)|([iI]gnored$)|(^ignored)", 31 | "argsIgnorePattern": "(^_+[0-9]*$)|([iI]gnored$)|(^ignored)" 32 | } 33 | ], 34 | "prettier/prettier": "error", 35 | "import/no-unresolved": [ 36 | "error", 37 | { 38 | "commonjs": true 39 | } 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Hardhat files 2 | cache 3 | artifacts 4 | 5 | # Hardhat deploy files 6 | deployments/localhost 7 | deployments/hardhat 8 | deployments/*/solcInputs/ 9 | 10 | # Created by https://www.toptal.com/developers/gitignore/api/vim,node,visualstudiocode,yarn 11 | # Edit at https://www.toptal.com/developers/gitignore?templates=vim,node,visualstudiocode,yarn 12 | 13 | ### Node ### 14 | # Logs 15 | logs 16 | *.log 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | lerna-debug.log* 21 | 22 | # Diagnostic reports (https://nodejs.org/api/report.html) 23 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 24 | 25 | # Runtime data 26 | pids 27 | *.pid 28 | *.seed 29 | *.pid.lock 30 | 31 | # Directory for instrumented libs generated by jscoverage/JSCover 32 | lib-cov 33 | 34 | # Coverage directory used by tools like istanbul 35 | coverage 36 | *.lcov 37 | 38 | # nyc test coverage 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | .grunt 43 | 44 | # Bower dependency directory (https://bower.io/) 45 | bower_components 46 | 47 | # node-waf configuration 48 | .lock-wscript 49 | 50 | # Compiled binary addons (https://nodejs.org/api/addons.html) 51 | build/Release 52 | 53 | # Dependency directories 54 | node_modules/ 55 | jspm_packages/ 56 | 57 | # TypeScript v1 declaration files 58 | typings/ 59 | 60 | # TypeScript cache 61 | *.tsbuildinfo 62 | 63 | # Optional npm cache directory 64 | .npm 65 | 66 | # Optional eslint cache 67 | .eslintcache 68 | 69 | # Microbundle cache 70 | .rpt2_cache/ 71 | .rts2_cache_cjs/ 72 | .rts2_cache_es/ 73 | .rts2_cache_umd/ 74 | 75 | # Optional REPL history 76 | .node_repl_history 77 | 78 | # Output of 'npm pack' 79 | *.tgz 80 | 81 | # Yarn Integrity file 82 | .yarn-integrity 83 | 84 | # dotenv environment variables file 85 | .env 86 | .env.test 87 | 88 | # parcel-bundler cache (https://parceljs.org/) 89 | .cache 90 | 91 | # Next.js build output 92 | .next 93 | 94 | # Nuxt.js build / generate output 95 | .nuxt 96 | dist 97 | 98 | # Gatsby files 99 | .cache/ 100 | # Comment in the public line in if your project uses Gatsby and not Next.js 101 | # https://nextjs.org/blog/next-9-1#public-directory-support 102 | # public 103 | 104 | # vuepress build output 105 | .vuepress/dist 106 | 107 | # Serverless directories 108 | .serverless/ 109 | 110 | # FuseBox cache 111 | .fusebox/ 112 | 113 | # DynamoDB Local files 114 | .dynamodb/ 115 | 116 | # TernJS port file 117 | .tern-port 118 | 119 | # Stores VSCode versions used for testing VSCode extensions 120 | .vscode-test 121 | 122 | ### Vim ### 123 | # Swap 124 | [._]*.s[a-v][a-z] 125 | !*.svg # comment out if you don't need vector files 126 | [._]*.sw[a-p] 127 | [._]s[a-rt-v][a-z] 128 | [._]ss[a-gi-z] 129 | [._]sw[a-p] 130 | 131 | # Session 132 | Session.vim 133 | Sessionx.vim 134 | 135 | # Temporary 136 | .netrwhist 137 | *~ 138 | # Auto-generated tag files 139 | tags 140 | # Persistent undo 141 | [._]*.un~ 142 | 143 | ### VisualStudioCode ### 144 | .vscode/* 145 | !.vscode/settings.json 146 | !.vscode/tasks.json 147 | !.vscode/launch.json 148 | !.vscode/extensions.json 149 | *.code-workspace 150 | 151 | ### VisualStudioCode Patch ### 152 | # Ignore all local history of files 153 | .history 154 | 155 | ### yarn ### 156 | # https://yarnpkg.com/advanced/qa#which-files-should-be-gitignored 157 | 158 | # .yarn/unplugged and .yarn/build-state.yml should likely always be ignored since 159 | # they typically hold machine-specific build artifacts. Ignoring them might however 160 | # prevent Zero-Installs from working (to prevent this, set enableScripts to false). 161 | .yarn/unplugged 162 | .yarn/build-state.yml 163 | 164 | # .yarn/cache and .pnp.* may be safely ignored, but you'll need to run yarn install 165 | # to regenerate them between each branch switch. 166 | # Uncomment the following lines if you're not using Zero-Installs: 167 | # .yarn/cache 168 | # .pnp.* 169 | 170 | # End of https://www.toptal.com/developers/gitignore/api/vim,node,visualstudiocode,yarn 171 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged 5 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.{json,md}": "prettier --write", 3 | "*.sol": "solhint --fix", 4 | "*.js": "eslint --fix" 5 | } 6 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "overrides": [ 4 | { 5 | "files": [ 6 | "*.json" 7 | ], 8 | "options": { 9 | "parser": "json-stringify" 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": [ 4 | "prettier" 5 | ], 6 | "rules": { 7 | "prettier/prettier": "error", 8 | "max-line-length": "off", 9 | "check-send-result": "off", 10 | "not-rely-on-time": "off", 11 | "multiple-sends": "off", 12 | "compiler-version": "off", 13 | "func-visibility": [ 14 | "warn", 15 | { 16 | "ignoreConstructors": true 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [2.0.0](https://github.com/kleros/tcr/compare/v1.9.2...v2.0.0) (2020-09-11) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * add item limit to items query ([2fdded2](https://github.com/kleros/tcr/commit/2fdded2)) 11 | 12 | ### [1.9.2](https://github.com/kleros/tcr/compare/v1.9.1...v1.9.2) (2020-08-06) 13 | 14 | ### Bug Fixes 15 | 16 | - add missing utils folder to package ([b65634d](https://github.com/kleros/tcr/commit/b65634d)) 17 | 18 | ### [1.9.1](https://github.com/kleros/tcr/compare/v1.9.0...v1.9.1) (2020-08-06) 19 | 20 | ### Bug Fixes 21 | 22 | - remove dependency on ethereum-libraries ([8690381](https://github.com/kleros/tcr/commit/8690381)) 23 | 24 | ## [1.9.0](https://github.com/kleros/tcr/compare/v1.7.0...v1.9.0) (2020-08-06) 25 | 26 | ### Bug Fixes 27 | 28 | - first round fee stake ([#24](https://github.com/kleros/tcr/issues/24)) ([590f239](https://github.com/kleros/tcr/commit/590f239)), closes [#25](https://github.com/kleros/tcr/issues/25) 29 | - wrong erc-792 package breaking build ([a23c394](https://github.com/kleros/tcr/commit/a23c394)) 30 | 31 | ## [1.9.0-alpha.1](https://github.com/kleros/tcr/compare/v1.8.1...v1.9.0-alpha.1) (2020-05-15) 32 | 33 | ### Features 34 | 35 | - allow filtering items by status ([1f88766](https://github.com/kleros/tcr/commit/1f88766)) 36 | - allow single column matching in findItem ([3b7de84](https://github.com/kleros/tcr/commit/3b7de84)) 37 | 38 | ## [1.9.0-alpha.0](https://github.com/kleros/tcr/compare/v1.8.1...v1.9.0-alpha.0) (2020-05-15) 39 | 40 | ### Features 41 | 42 | - allow single column matching in findItem ([236ae6f](https://github.com/kleros/tcr/commit/236ae6f)) 43 | 44 | ### [1.8.1](https://github.com/kleros/tcr/compare/v1.7.0...v1.8.1) (2020-05-11) 45 | 46 | ### Bug Fixes 47 | 48 | - add missing field in round getter and update view contract ([1a8fa61](https://github.com/kleros/tcr/commit/1a8fa61)) 49 | - docs and error message ([abab004](https://github.com/kleros/tcr/commit/abab004)) 50 | - don't require fee stake in the first round ([4f3bdde](https://github.com/kleros/tcr/commit/4f3bdde)) 51 | - move evidenceGroupID mapping to event logs ([97feccd](https://github.com/kleros/tcr/commit/97feccd)) 52 | - reduce complexity on withdrawFeesAndRewards ([fb7595f](https://github.com/kleros/tcr/commit/fb7595f)) 53 | - reimbursement and fee withdrawal ([3f62396](https://github.com/kleros/tcr/commit/3f62396)) 54 | - remove the request type since is available on event logs ([9e7046c](https://github.com/kleros/tcr/commit/9e7046c)) 55 | - remove unused struct field ([c80b05a](https://github.com/kleros/tcr/commit/c80b05a)) 56 | - typo, bug and useless condition ([911f71f](https://github.com/kleros/tcr/commit/911f71f)) 57 | - update compiler version ([29ebd6b](https://github.com/kleros/tcr/commit/29ebd6b)) 58 | 59 | ## [1.8.0](https://github.com/kleros/tcr/compare/v1.5.1...v1.8.0) (2020-04-27) 60 | 61 | ### Bug Fixes 62 | 63 | - add missing field in round getter and update view contract ([bf877e5](https://github.com/kleros/tcr/commit/bf877e5)) 64 | - don't require fee stake in the first round ([7eabae7](https://github.com/kleros/tcr/commit/7eabae7)) 65 | - reduce complexity on withdrawFeesAndRewards ([1d5fba1](https://github.com/kleros/tcr/commit/1d5fba1)) 66 | - reimbursement and fee withdrawal ([ca27499](https://github.com/kleros/tcr/commit/ca27499)) 67 | - remove unused struct field ([b869987](https://github.com/kleros/tcr/commit/b869987)) 68 | - typo, bug and useless condition ([f4d60e5](https://github.com/kleros/tcr/commit/f4d60e5)) 69 | 70 | ### Features 71 | 72 | - implement review suggestions ([0b380cf](https://github.com/kleros/tcr/commit/0b380cf)) 73 | 74 | ### [1.7.1](https://github.com/kleros/tcr/compare/v1.7.0...v1.7.1) (2020-04-03) 75 | 76 | ## [1.7.0](https://github.com/kleros/tcr/compare/v1.5.1...v1.7.0) (2020-04-27) 77 | 78 | ### Bug Fixes 79 | 80 | - add missing field in round getter and update view contract ([bf877e5](https://github.com/kleros/tcr/commit/bf877e5)) 81 | - don't require fee stake in the first round ([7eabae7](https://github.com/kleros/tcr/commit/7eabae7)) 82 | - reduce complexity on withdrawFeesAndRewards ([1d5fba1](https://github.com/kleros/tcr/commit/1d5fba1)) 83 | - reimbursement and fee withdrawal ([ca27499](https://github.com/kleros/tcr/commit/ca27499)) 84 | - remove unused struct field ([b869987](https://github.com/kleros/tcr/commit/b869987)) 85 | - typo, bug and useless condition ([f4d60e5](https://github.com/kleros/tcr/commit/f4d60e5)) 86 | 87 | ### Features 88 | 89 | - implement review suggestions ([0b380cf](https://github.com/kleros/tcr/commit/0b380cf)) 90 | 91 | ## [1.6.0](https://github.com/kleros/tcr/compare/v1.5.1...v1.6.0) (2020-03-18) 92 | 93 | ### Features 94 | 95 | - implement review suggestions ([0b380cf](https://github.com/kleros/tcr/commit/0b380cf)) 96 | 97 | ### [1.5.1](https://github.com/kleros/tcr/compare/v1.5.0...v1.5.1) (2020-03-09) 98 | 99 | ### Bug Fixes 100 | 101 | - add missing docstring and be consistent with parameter names ([6cce5ac](https://github.com/kleros/tcr/commit/6cce5ac)) 102 | 103 | ## [1.5.0](https://github.com/kleros/tcr/compare/v1.4.2...v1.5.0) (2020-03-09) 104 | 105 | ### Bug Fixes 106 | 107 | - don't cast instance to address ([af3fecb](https://github.com/kleros/tcr/commit/af3fecb)) 108 | - find index when sorting oldest first ([749759f](https://github.com/kleros/tcr/commit/749759f)) 109 | 110 | ### Features 111 | 112 | - include evidence group in item and request events ([6635ed2](https://github.com/kleros/tcr/commit/6635ed2)) 113 | 114 | ### [1.4.4](https://github.com/kleros/tcr/compare/v1.4.2...v1.4.4) (2020-02-26) 115 | 116 | ### Bug Fixes 117 | 118 | - don't cast instance to address ([a65bdd2](https://github.com/kleros/tcr/commit/a65bdd2)) 119 | 120 | ### [1.4.2](https://github.com/kleros/tcr/compare/v1.4.0...v1.4.2) (2020-02-04) 121 | 122 | ## [1.4.0](https://github.com/kleros/tcr/compare/v1.3.1...v1.4.0) (2020-01-24) 123 | 124 | ### Features 125 | 126 | - allow providing evidence for removal requests] ([ff688e8](https://github.com/kleros/tcr/commit/ff688e8)) 127 | 128 | ### [1.3.1](https://github.com/kleros/tcr/compare/v1.3.0...v1.3.1) (2020-01-23) 129 | 130 | ## [1.3.0](https://github.com/kleros/tcr/compare/v1.2.0...v1.3.0) (2020-01-22) 131 | 132 | ### Features 133 | 134 | - add factory contract ([6906fcb](https://github.com/kleros/tcr/commit/6906fcb)) 135 | 136 | ## [1.2.0](https://github.com/kleros/tcr/compare/v1.1.0...v1.2.0) (2020-01-15) 137 | 138 | ### Features 139 | 140 | - also return the arbitraion cost in fetch arbitrable ([2e3cc06](https://github.com/kleros/tcr/commit/2e3cc06)) 141 | 142 | ## [1.1.0](https://github.com/kleros/tcr/compare/v1.0.3...v1.1.0) (2020-01-14) 143 | 144 | ### Features 145 | 146 | - add flag to not return absent items by default ([e7a7f94](https://github.com/kleros/tcr/commit/e7a7f94)) 147 | 148 | ### [1.0.3](https://github.com/kleros/tcr/compare/v1.0.2...v1.0.3) (2020-01-13) 149 | 150 | ### [1.0.2](https://github.com/kleros/tcr/compare/v1.0.1...v1.0.2) (2020-01-13) 151 | 152 | ### Bug Fixes 153 | 154 | - incorrect result array instantiation ([8ec75a3](https://github.com/kleros/tcr/commit/8ec75a3)) 155 | 156 | ### [1.0.1](https://github.com/kleros/tcr/compare/v1.0.0...v1.0.1) (2020-01-13) 157 | 158 | ## [1.0.0](https://github.com/kleros/tcr/compare/v0.1.31...v1.0.0) (2020-01-02) 159 | 160 | ### Bug Fixes 161 | 162 | - review suggestions ([d51a333](https://github.com/kleros/tcr/commit/d51a333)) 163 | 164 | ### [0.1.31](https://github.com/kleros/tcr/compare/v0.1.29...v0.1.31) (2019-12-27) 165 | 166 | ### Bug Fixes 167 | 168 | - incorrect argument and iterator reset ([87b7f85](https://github.com/kleros/tcr/commit/87b7f85)) 169 | 170 | ### Features 171 | 172 | - add batch withdraw contract ([8e9215f](https://github.com/kleros/tcr/commit/8e9215f)) 173 | - add view function for available rewards ([68b23d7](https://github.com/kleros/tcr/commit/68b23d7)) 174 | 175 | ### [0.1.30](https://github.com/kleros/tcr/compare/v0.1.29...v0.1.30) (2019-12-27) 176 | 177 | ### Features 178 | 179 | - add view function for available rewards ([68b23d7](https://github.com/kleros/tcr/commit/68b23d7)) 180 | 181 | ### [0.1.29](https://github.com/kleros/tcr/compare/v0.1.28...v0.1.29) (2019-12-18) 182 | 183 | ### [0.1.28](https://github.com/kleros/tcr/compare/v0.1.27...v0.1.28) (2019-12-08) 184 | 185 | ### Features 186 | 187 | - include mapping of evidenceGroupID to requestID ([47f3fdf](https://github.com/kleros/tcr/commit/47f3fdf)) 188 | 189 | ### [0.1.27](https://github.com/kleros/tcr/compare/v0.1.24...v0.1.27) (2019-12-06) 190 | 191 | ### Features 192 | 193 | - include the request type in RequestSubmitted event ([4285f96](https://github.com/kleros/tcr/commit/4285f96)) 194 | - make index ItemStatusChange fields and add request status fields ([07f52c1](https://github.com/kleros/tcr/commit/07f52c1)) 195 | 196 | ### [0.1.25](https://github.com/kleros/tcr/compare/v0.1.24...v0.1.25) (2019-12-04) 197 | 198 | ### Features 199 | 200 | - include the request type in RequestSubmitted event ([02bae44](https://github.com/kleros/tcr/commit/02bae44)) 201 | 202 | ### [0.1.24](https://github.com/kleros/tcr/compare/v0.1.21...v0.1.24) (2019-12-01) 203 | 204 | ### Bug Fixes 205 | 206 | - implement clements review suggestions ([5662747](https://github.com/kleros/tcr/commit/5662747)) 207 | - implement review suggestions ([0121161](https://github.com/kleros/tcr/commit/0121161)) 208 | 209 | ### [0.1.23](https://github.com/kleros/tcr/compare/v0.1.21...v0.1.23) (2019-11-30) 210 | 211 | ### Bug Fixes 212 | 213 | - implement clements review suggestions ([5662747](https://github.com/kleros/tcr/commit/5662747)) 214 | - implement review suggestions ([eb57b6c](https://github.com/kleros/tcr/commit/eb57b6c)) 215 | 216 | ### [0.1.21](https://github.com/kleros/tcr/compare/v0.1.19...v0.1.21) (2019-10-26) 217 | 218 | ### Features 219 | 220 | - return the meta evidence ID for the request ([4ba27ec](https://github.com/kleros/tcr/commit/4ba27ec)) 221 | 222 | ### [0.1.19](https://github.com/kleros/tcr/compare/v0.1.15...v0.1.19) (2019-10-26) 223 | 224 | ### Bug Fixes 225 | 226 | - lock meta evidence and close [#5](https://github.com/kleros/tcr/issues/5) ([08ff5f8](https://github.com/kleros/tcr/commit/08ff5f8)) 227 | 228 | ### Features 229 | 230 | - **GTCR.sol:** test file ([#7](https://github.com/kleros/tcr/issues/7)) ([963bf28](https://github.com/kleros/tcr/commit/963bf28)) 231 | - emit event on appeal crowdfunding contribution ([7ab6860](https://github.com/kleros/tcr/commit/7ab6860)) 232 | - emit event when someone submits a request ([2f52566](https://github.com/kleros/tcr/commit/2f52566)) 233 | - save the item's position on the list ([1deb2be](https://github.com/kleros/tcr/commit/1deb2be)) 234 | - submit event on item submission ([#9](https://github.com/kleros/tcr/issues/9)) ([5d66530](https://github.com/kleros/tcr/commit/5d66530)) 235 | 236 | ### [0.1.18](https://github.com/kleros/tcr/compare/v0.1.15...v0.1.18) (2019-10-01) 237 | 238 | ### Features 239 | 240 | - **GTCR.sol:** test file ([#7](https://github.com/kleros/tcr/issues/7)) ([963bf28](https://github.com/kleros/tcr/commit/963bf28)) 241 | - remove support for EIP165 to avoid complexity ([1e83dbc](https://github.com/kleros/tcr/commit/1e83dbc)) 242 | - use kleros libraries instead of local contracts ([64db9fd](https://github.com/kleros/tcr/commit/64db9fd)) 243 | 244 | ### [0.1.15](https://github.com/kleros/tcr/compare/v0.1.14...v0.1.15) (2019-09-14) 245 | 246 | ### Bug Fixes 247 | 248 | - readd item requests and remove simple request ([2d3dd74](https://github.com/kleros/tcr/commit/2d3dd74)) 249 | 250 | ### [0.1.14](https://github.com/kleros/tcr/compare/v0.1.13...v0.1.14) (2019-09-14) 251 | 252 | ### Features 253 | 254 | - save request type in storage for history ([67d8eed](https://github.com/kleros/tcr/commit/67d8eed)) 255 | 256 | ### [0.1.13](https://github.com/kleros/tcr/compare/v0.1.12...v0.1.13) (2019-09-14) 257 | 258 | ### Bug Fixes 259 | 260 | - remove unecessary vars ([834ec94](https://github.com/kleros/tcr/commit/834ec94)) 261 | - use a more descriptive function name ([83963d1](https://github.com/kleros/tcr/commit/83963d1)) 262 | - wrong page index when there aren't enought items to fill a page ([de1fb2d](https://github.com/kleros/tcr/commit/de1fb2d)) 263 | 264 | ### Features 265 | 266 | - add getItemRequests function, docs and remove unused vars ([f14a6d0](https://github.com/kleros/tcr/commit/f14a6d0)) 267 | - also return the number of requests and make methods public ([6f48a5b](https://github.com/kleros/tcr/commit/6f48a5b)) 268 | 269 | ### [0.1.12](https://github.com/kleros/tcr/compare/v0.1.11...v0.1.12) (2019-08-28) 270 | 271 | ### Bug Fixes 272 | 273 | - hasMore check ([d92bd42](https://github.com/kleros/tcr/commit/d92bd42)) 274 | - incorrect hasMore setting ([31816a0](https://github.com/kleros/tcr/commit/31816a0)) 275 | 276 | ### [0.1.11](https://github.com/kleros/tcr/compare/v0.1.10...v0.1.11) (2019-08-28) 277 | 278 | ### Features 279 | 280 | - return last index if target was not found ([1b8614f](https://github.com/kleros/tcr/commit/1b8614f)) 281 | 282 | ### [0.1.10](https://github.com/kleros/tcr/compare/v0.1.9...v0.1.10) (2019-08-28) 283 | 284 | ### Bug Fixes 285 | 286 | - execution error on queryItems and findIndexFor page for empty tcrs ([ed280da](https://github.com/kleros/tcr/commit/ed280da)) 287 | 288 | ### Features 289 | 290 | - add countWithFilter() and return indexFound on findIndexForPage ([04da768](https://github.com/kleros/tcr/commit/04da768)) 291 | 292 | ### [0.1.9](https://github.com/kleros/tcr/compare/v0.1.8...v0.1.9) (2019-08-28) 293 | 294 | ### Bug Fixes 295 | 296 | - queryItems returning only one item with oldestFirst == false ([fd82dc6](https://github.com/kleros/tcr/commit/fd82dc6)) 297 | 298 | ### [0.1.8](https://github.com/kleros/tcr/compare/v0.1.7...v0.1.8) (2019-08-27) 299 | 300 | ### Features 301 | 302 | - add find index for page view function ([c76d288](https://github.com/kleros/tcr/commit/c76d288)) 303 | 304 | ### [0.1.7](https://github.com/kleros/tcr/compare/v0.1.6...v0.1.7) (2019-08-24) 305 | 306 | ### Bug Fixes 307 | 308 | - queryItems iteration ([c85060b](https://github.com/kleros/tcr/commit/c85060b)) 309 | 310 | ### [0.1.6](https://github.com/kleros/tcr/compare/v0.1.5...v0.1.6) (2019-08-23) 311 | 312 | ### Bug Fixes 313 | 314 | - enable optimizer ([60f836b](https://github.com/kleros/tcr/commit/60f836b)) 315 | - enable optimizer and remove obsolete instructions ([3d65c9a](https://github.com/kleros/tcr/commit/3d65c9a)) 316 | 317 | ### [0.1.5](https://github.com/kleros/tcr/compare/v0.1.4...v0.1.5) (2019-08-23) 318 | 319 | ### Bug Fixes 320 | 321 | - add/remove missing and obsolete abis ([b62e317](https://github.com/kleros/tcr/commit/b62e317)) 322 | - let the package users build the contracts ([3259df1](https://github.com/kleros/tcr/commit/3259df1)) 323 | 324 | ### Features 325 | 326 | - emit event on item status change ([c341007](https://github.com/kleros/tcr/commit/c341007)) 327 | 328 | ### [0.1.4](https://github.com/kleros/tcr/compare/v0.1.3...v0.1.4) (2019-08-23) 329 | 330 | ### Features 331 | 332 | - add introspection for the IArbitrable interface ([c5e4bc3](https://github.com/kleros/tcr/commit/c5e4bc3)) 333 | - remove unused permission interface ([f5e339b](https://github.com/kleros/tcr/commit/f5e339b)) 334 | - use proxy methods to requestStatusChange to avoid accidents ([69948d6](https://github.com/kleros/tcr/commit/69948d6)) 335 | 336 | ### [0.1.3](https://github.com/kleros/tcr/compare/v0.1.2...v0.1.3) (2019-08-23) 337 | 338 | ### Features 339 | 340 | - add view contract and remove obsolete ([26733d4](https://github.com/kleros/tcr/commit/26733d4)) 341 | 342 | ### [0.1.2](https://github.com/kleros/tcr/compare/v0.1.1...v0.1.2) (2019-08-22) 343 | 344 | ### Features 345 | 346 | - add contract abis to package ([1a4d405](https://github.com/kleros/tcr/commit/1a4d405)) 347 | 348 | ### 0.1.1 (2019-08-22) 349 | 350 | ### Bug Fixes 351 | 352 | - **GTCR:** addressing recent issues ([b5483b8](https://github.com/kleros/tcr/commit/b5483b8)) 353 | - add missing packages that prevent scripts from running properly ([f62a0ff](https://github.com/kleros/tcr/commit/f62a0ff)) 354 | - **GTCR:** removed addItem function ([e7741f7](https://github.com/kleros/tcr/commit/e7741f7)) 355 | - **GTCR:** small query items fix ([f927310](https://github.com/kleros/tcr/commit/f927310)) 356 | 357 | ### Features 358 | 359 | - **GTCR:** added GTCR contract with dependencies ([504e574](https://github.com/kleros/tcr/commit/504e574)) 360 | - include view contracts and upgrade compiler to 0.5.11 ([49d6e26](https://github.com/kleros/tcr/commit/49d6e26)) 361 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Smart Contract Solutions, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Arbitrable Permission Lists on Ethereum 3 |

4 | 5 |

6 | JavaScript Style Guide 7 | Tested with Truffle 8 | Conventional Commits 9 | Commitizen Friendly 10 | Styled with Prettier 11 |

12 | 13 | Contracts for creating arbitrable permission lists on Ethereum. 14 | 15 | ## Development 16 | 17 | 1. Clone this repo. 18 | 2. Run `yarn install` to install dependencies and then `yarn build` to compile the contracts. 19 | 20 | ## Release 21 | 22 | To bump the version of the package, use `yarn release`. 23 | 24 | ## Scripts 25 | 26 | - `yarn prettify` - Apply prettier to the entire project. 27 | - `yarn lint:sol` - Lint the entire project's .sol files. 28 | - `yarn lint:js` - Lint the entire project's .js files. 29 | - `yarn lint:sol --fix` - Fix fixable linting errors in .sol files. 30 | - `yarn lint:js --fix` - Fix fixable linting errors in .js files. 31 | - `yarn lint` - Lint the entire project's .sol and .js files. 32 | - `yarn test` - Run the truffle tests. 33 | - `yarn cz` - Run commitizen. 34 | - `yarn build` - Compiles contracts and extracts the abi into the abi folder. 35 | - `yarn release` - Run standard-version`. 36 | 37 | ## Test 38 | 39 | Testrpc default gas limit is lower than the mainnet which prevents deploying some contracts. Before running truffle tests use: 40 | `testrpc -l 8000000`. 41 | 42 | ## Testing contracts 43 | 44 | - Run `npx hardhat compile` to compile the contracts. 45 | - Run `npx hardhat test` to run all test cases in test folder. 46 | - Run `npx hardhat test ` to run the test cases for specific contract. 47 | 48 | ## Testing contracts on specific network 49 | 50 | - Run `npx hardhat test --network ` to run all test cases in test folder. 51 | - Run `npx hardhat test --network ` to run the test cases for specific contract. 52 | - Add private keys for the roles needed to test the contracts according to hardhat.config.js. 53 | 54 | ## Contributing 55 | 56 | See [contributing](https://kleros.gitbook.io/contributing-md/). 57 | 58 | Learn how to develop arbitrable and arbitrator contracts [here](https://erc-792.readthedocs.io/en/latest/). 59 | -------------------------------------------------------------------------------- /contracts/BatchWithdraw.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc] 3 | * @reviewers: [] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.16; 10 | 11 | import { GeneralizedTCR } from "./GeneralizedTCR.sol"; 12 | 13 | /** 14 | * @title BatchWithdraw 15 | * Withdraw fees and rewards from contributions to disputes rounds in batches. 16 | */ 17 | contract BatchWithdraw { 18 | 19 | /** @dev Withdraws rewards and reimbursements of multiple rounds at once. This function is O(n) where n is the number of rounds. This could exceed gas limits, therefore this function should be used only as a utility and not be relied upon by other contracts. 20 | * @param _address The address of the GTCR. 21 | * @param _contributor The address that made contributions to the request. 22 | * @param _itemID The ID of the item with funds to be withdrawn. 23 | * @param _request The request from which to withdraw contributions. 24 | * @param _cursor The round from where to start withdrawing. 25 | * @param _count The number of rounds to iterate. If set to 0 or a value larger than the number of rounds, iterates until the last round. 26 | */ 27 | function batchRoundWithdraw( 28 | address _address, 29 | address payable _contributor, 30 | bytes32 _itemID, 31 | uint _request, 32 | uint _cursor, 33 | uint _count 34 | ) public { 35 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 36 | (,,,,,uint numberOfRounds,,,,) = gtcr.getRequestInfo(_itemID, _request); 37 | for (uint i = _cursor; i < numberOfRounds && (_count == 0 || i < _count); i++) 38 | gtcr.withdrawFeesAndRewards(_contributor, _itemID, _request, i); 39 | } 40 | 41 | /** @dev Withdraws rewards and reimbursements of multiple requests at once. This function is O(n*m) where n is the number of requests and m is the number of rounds to withdraw per request. This could exceed gas limits, therefore this function should be used only as a utility and not be relied upon by other contracts. 42 | * @param _address The address of the GTCR. 43 | * @param _contributor The address that made contributions to the request. 44 | * @param _itemID The ID of the item with funds to be withdrawn. 45 | * @param _cursor The request from which to start withdrawing. 46 | * @param _count The number of requests to iterate. If set to 0 or a value larger than the number of request, iterates until the last request. 47 | * @param _roundCursor The round of each request from where to start withdrawing. 48 | * @param _roundCount The number of rounds to iterate on each request. If set to 0 or a value larger than the number of rounds a request has, iteration for that request will stop at the last round. 49 | */ 50 | function batchRequestWithdraw( 51 | address _address, 52 | address payable _contributor, 53 | bytes32 _itemID, 54 | uint _cursor, 55 | uint _count, 56 | uint _roundCursor, 57 | uint _roundCount 58 | ) external { 59 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 60 | ( 61 | , 62 | , 63 | uint numberOfRequests 64 | ) = gtcr.getItemInfo(_itemID); 65 | for (uint i = _cursor; i < numberOfRequests && (_count == 0 || i < _count); i++) 66 | batchRoundWithdraw(_address, _contributor, _itemID, i, _roundCursor, _roundCount); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /contracts/GTCRFactory.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc] 3 | * @reviewers: [@clesaege, @unknownunknown1, @ferittuncer, @satello, @MerlinEgalite] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.16; 10 | 11 | import { GeneralizedTCR, IArbitrator } from "./GeneralizedTCR.sol"; 12 | 13 | /* solium-disable max-len */ 14 | 15 | /** 16 | * @title GTCRFactory 17 | * This contract acts as a registry for GeneralizedTCR instances. 18 | */ 19 | contract GTCRFactory { 20 | 21 | /** 22 | * @dev Emitted when a new Generalized TCR contract is deployed using this factory. 23 | * @param _address The address of the newly deployed Generalized TCR. 24 | */ 25 | event NewGTCR(GeneralizedTCR indexed _address); 26 | 27 | GeneralizedTCR[] public instances; 28 | 29 | /** 30 | * @dev Deploy the arbitrable curated registry. 31 | * @param _arbitrator Arbitrator to resolve potential disputes. The arbitrator is trusted to support appeal periods and not reenter. 32 | * @param _arbitratorExtraData Extra data for the trusted arbitrator contract. 33 | * @param _connectedTCR The address of the TCR that stores related TCR addresses. This parameter can be left empty. 34 | * @param _registrationMetaEvidence The URI of the meta evidence object for registration requests. 35 | * @param _clearingMetaEvidence The URI of the meta evidence object for clearing requests. 36 | * @param _governor The trusted governor of this contract. 37 | * @param _submissionBaseDeposit The base deposit to submit an item. 38 | * @param _removalBaseDeposit The base deposit to remove an item. 39 | * @param _submissionChallengeBaseDeposit The base deposit to challenge a submission. 40 | * @param _removalChallengeBaseDeposit The base deposit to challenge a removal request. 41 | * @param _challengePeriodDuration The time in seconds parties have to challenge a request. 42 | * @param _stakeMultipliers Multipliers of the arbitration cost in basis points (see GeneralizedTCR MULTIPLIER_DIVISOR) as follows: 43 | * - The multiplier applied to each party's fee stake for a round when there is no winner/loser in the previous round (e.g. when it's the first round or the arbitrator refused to arbitrate). 44 | * - The multiplier applied to the winner's fee stake for an appeal round. 45 | * - The multiplier applied to the loser's fee stake for an appeal round. 46 | */ 47 | function deploy( 48 | IArbitrator _arbitrator, 49 | bytes memory _arbitratorExtraData, 50 | address _connectedTCR, 51 | string memory _registrationMetaEvidence, 52 | string memory _clearingMetaEvidence, 53 | address _governor, 54 | uint _submissionBaseDeposit, 55 | uint _removalBaseDeposit, 56 | uint _submissionChallengeBaseDeposit, 57 | uint _removalChallengeBaseDeposit, 58 | uint _challengePeriodDuration, 59 | uint[3] memory _stakeMultipliers 60 | ) public { 61 | GeneralizedTCR instance = new GeneralizedTCR( 62 | _arbitrator, 63 | _arbitratorExtraData, 64 | _connectedTCR, 65 | _registrationMetaEvidence, 66 | _clearingMetaEvidence, 67 | _governor, 68 | _submissionBaseDeposit, 69 | _removalBaseDeposit, 70 | _submissionChallengeBaseDeposit, 71 | _removalChallengeBaseDeposit, 72 | _challengePeriodDuration, 73 | _stakeMultipliers 74 | ); 75 | instances.push(instance); 76 | emit NewGTCR(instance); 77 | } 78 | 79 | /** 80 | * @return The number of deployed tcrs using this factory. 81 | */ 82 | function count() external view returns (uint) { 83 | return instances.length; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /contracts/LightBatchWithdraw.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc] 3 | * @reviewers: [] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.16; 10 | 11 | import {LightGeneralizedTCR} from "./LightGeneralizedTCR.sol"; 12 | 13 | /** 14 | * @title LightBatchWithdraw 15 | * Withdraw fees and rewards from contributions to disputes rounds in batches. 16 | */ 17 | contract LightBatchWithdraw { 18 | /** @dev Withdraws rewards and reimbursements of multiple rounds at once. This function is O(n) where n is the number of rounds. This could exceed gas limits, therefore this function should be used only as a utility and not be relied upon by other contracts. 19 | * @param _address The address of the LightGTCR. 20 | * @param _contributor The address that made contributions to the request. 21 | * @param _itemID The ID of the item with funds to be withdrawn. 22 | * @param _request The request from which to withdraw contributions. 23 | * @param _cursor The round from where to start withdrawing. Round 0 is always empty, so callers can safely start with 1. 24 | * @param _count The number of rounds to iterate. If set to 0 or a value larger than the number of rounds, iterates until the last round. 25 | */ 26 | function batchRoundWithdraw( 27 | address _address, 28 | address payable _contributor, 29 | bytes32 _itemID, 30 | uint256 _request, 31 | uint256 _cursor, 32 | uint256 _count 33 | ) public { 34 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 35 | (, , , , , uint256 numberOfRounds, , , , ) = gtcr.getRequestInfo(_itemID, _request); 36 | for (uint256 i = _cursor; i < numberOfRounds && (_count == 0 || i < _cursor + _count); i++) 37 | gtcr.withdrawFeesAndRewards(_contributor, _itemID, _request, i); 38 | } 39 | 40 | /** @dev Withdraws rewards and reimbursements of multiple requests at once. This function is O(n*m) where n is the number of requests and m is the number of rounds to withdraw per request. This could exceed gas limits, therefore this function should be used only as a utility and not be relied upon by other contracts. 41 | * @param _address The address of the GTCR. 42 | * @param _contributor The address that made contributions to the request. 43 | * @param _itemID The ID of the item with funds to be withdrawn. 44 | * @param _cursor The request from which to start withdrawing. 45 | * @param _count The number of requests to iterate. If set to 0 or a value larger than the number of request, iterates until the last request. 46 | * @param _roundCursor The round of each request from where to start withdrawing. Round 0 is always empty, so callers can safely start with 1. 47 | * @param _roundCount The number of rounds to iterate on each request. If set to 0 or a value larger than the number of rounds a request has, iteration for that request will stop at the last round. 48 | */ 49 | function batchRequestWithdraw( 50 | address _address, 51 | address payable _contributor, 52 | bytes32 _itemID, 53 | uint256 _cursor, 54 | uint256 _count, 55 | uint256 _roundCursor, 56 | uint256 _roundCount 57 | ) external { 58 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 59 | (, uint256 numberOfRequests, ) = gtcr.getItemInfo(_itemID); 60 | for (uint256 i = _cursor; i < numberOfRequests && (_count == 0 || i < _cursor + _count); i++) 61 | batchRoundWithdraw(_address, _contributor, _itemID, i, _roundCursor, _roundCount); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/LightGTCRFactory.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc] 3 | * @reviewers: [@fnanni-0, @shalzz] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.16; 10 | 11 | import {LightGeneralizedTCR, IArbitrator} from "./LightGeneralizedTCR.sol"; 12 | 13 | /* solium-disable max-len */ 14 | 15 | /** 16 | * @title LightGTCRFactory 17 | * This contract acts as a registry for LightGeneralizedTCR instances. 18 | */ 19 | contract LightGTCRFactory { 20 | /** 21 | * @dev Emitted when a new Generalized TCR contract is deployed using this factory. 22 | * @param _address The address of the newly deployed Generalized TCR. 23 | */ 24 | event NewGTCR(LightGeneralizedTCR indexed _address); 25 | 26 | LightGeneralizedTCR[] public instances; 27 | address public GTCR; 28 | 29 | /** 30 | * @dev Constructor. 31 | * @param _GTCR Address of the generalized TCR contract that is going to be used for each new deployment. 32 | */ 33 | constructor(address _GTCR) public { 34 | GTCR = _GTCR; 35 | } 36 | 37 | /** 38 | * @dev Deploy the arbitrable curated registry. 39 | * @param _arbitrator Arbitrator to resolve potential disputes. The arbitrator is trusted to support appeal periods and not reenter. 40 | * @param _arbitratorExtraData Extra data for the trusted arbitrator contract. 41 | * @param _connectedTCR The address of the TCR that stores related TCR addresses. This parameter can be left empty. 42 | * @param _registrationMetaEvidence The URI of the meta evidence object for registration requests. 43 | * @param _clearingMetaEvidence The URI of the meta evidence object for clearing requests. 44 | * @param _governor The trusted governor of this contract. 45 | * @param _baseDeposits The base deposits for requests/challenges as follows: 46 | * - The base deposit to submit an item. 47 | * - The base deposit to remove an item. 48 | * - The base deposit to challenge a submission. 49 | * - The base deposit to challenge a removal request. 50 | * @param _challengePeriodDuration The time in seconds parties have to challenge a request. 51 | * @param _stakeMultipliers Multipliers of the arbitration cost in basis points (see LightGeneralizedTCR MULTIPLIER_DIVISOR) as follows: 52 | * - The multiplier applied to each party's fee stake for a round when there is no winner/loser in the previous round. 53 | * - The multiplier applied to the winner's fee stake for an appeal round. 54 | * - The multiplier applied to the loser's fee stake for an appeal round. 55 | * @param _relayContract The address of the relay contract to add/remove items directly. 56 | */ 57 | function deploy( 58 | IArbitrator _arbitrator, 59 | bytes memory _arbitratorExtraData, 60 | address _connectedTCR, 61 | string memory _registrationMetaEvidence, 62 | string memory _clearingMetaEvidence, 63 | address _governor, 64 | uint256[4] memory _baseDeposits, 65 | uint256 _challengePeriodDuration, 66 | uint256[3] memory _stakeMultipliers, 67 | address _relayContract 68 | ) public { 69 | LightGeneralizedTCR instance = clone(GTCR); 70 | instance.initialize( 71 | _arbitrator, 72 | _arbitratorExtraData, 73 | _connectedTCR, 74 | _registrationMetaEvidence, 75 | _clearingMetaEvidence, 76 | _governor, 77 | _baseDeposits, 78 | _challengePeriodDuration, 79 | _stakeMultipliers, 80 | _relayContract 81 | ); 82 | instances.push(instance); 83 | emit NewGTCR(instance); 84 | } 85 | 86 | /** 87 | * @notice Adaptation of @openzeppelin/contracts/proxy/Clones.sol. 88 | * @dev Deploys and returns the address of a clone that mimics the behaviour of `GTCR`. 89 | * @param _implementation Address of the contract to clone. 90 | * This function uses the create opcode, which should never revert. 91 | */ 92 | function clone(address _implementation) internal returns (LightGeneralizedTCR instance) { 93 | assembly { 94 | let ptr := mload(0x40) 95 | mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 96 | mstore(add(ptr, 0x14), shl(0x60, _implementation)) 97 | mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 98 | instance := create(0, ptr, 0x37) 99 | } 100 | require(instance != LightGeneralizedTCR(0), "ERC1167: create failed"); 101 | } 102 | 103 | /** 104 | * @return The number of deployed tcrs using this factory. 105 | */ 106 | function count() external view returns (uint256) { 107 | return instances.length; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /contracts/test-purposes/AppealableArbitrator.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * https://contributing.kleros.io/smart-contract-workflow 3 | * @authors: [@epiqueras, @ferittuncer, @unknownunknown1, @mtsalenc] 4 | * @reviewers: [] 5 | * @auditors: [] 6 | * @bounties: [] 7 | * @deployments: [] 8 | */ 9 | 10 | pragma solidity ^0.5.11; 11 | 12 | import "./CentralizedArbitrator.sol"; 13 | 14 | /** 15 | * @title AppealableArbitrator 16 | * @dev A centralized arbitrator that can be appealed. 17 | */ 18 | contract AppealableArbitrator is CentralizedArbitrator, IArbitrable { 19 | /* Structs */ 20 | 21 | struct AppealDispute { 22 | uint rulingTime; 23 | IArbitrator arbitrator; 24 | uint appealDisputeID; 25 | } 26 | 27 | /* Modifiers */ 28 | 29 | modifier onlyArbitrator {require(msg.sender == address(arbitrator), "Can only be called by the arbitrator."); _;} 30 | modifier requireAppealFee(uint _disputeID, bytes memory _extraData) { 31 | require(msg.value >= appealCost(_disputeID, _extraData), "Not enough ETH to cover appeal costs."); 32 | _; 33 | } 34 | 35 | /* Storage */ 36 | 37 | uint public timeOut; 38 | mapping(uint => AppealDispute) public appealDisputes; 39 | mapping(uint => uint) public appealDisputeIDsToDisputeIDs; 40 | IArbitrator public arbitrator; 41 | bytes public arbitratorExtraData; // Extra data to require particular dispute and appeal behaviour. 42 | 43 | /* Constructor */ 44 | 45 | /** @dev Constructs the `AppealableArbitrator` contract. 46 | * @param _arbitrationPrice The amount to be paid for arbitration. 47 | * @param _arbitrator The back up arbitrator. 48 | * @param _arbitratorExtraData Not used by this contract. 49 | * @param _timeOut The time out for the appeal period. 50 | */ 51 | constructor( 52 | uint _arbitrationPrice, 53 | IArbitrator _arbitrator, 54 | bytes memory _arbitratorExtraData, 55 | uint _timeOut 56 | ) public CentralizedArbitrator(_arbitrationPrice) { 57 | timeOut = _timeOut; 58 | } 59 | 60 | /* External */ 61 | 62 | /** @dev Changes the back up arbitrator. 63 | * @param _arbitrator The new back up arbitrator. 64 | */ 65 | function changeArbitrator(IArbitrator _arbitrator) external onlyOwner { 66 | arbitrator = _arbitrator; 67 | } 68 | 69 | /** @dev Changes the time out. 70 | * @param _timeOut The new time out. 71 | */ 72 | function changeTimeOut(uint _timeOut) external onlyOwner { 73 | timeOut = _timeOut; 74 | } 75 | 76 | /* External Views */ 77 | 78 | /** @dev Gets the specified dispute's latest appeal ID. 79 | * @param _disputeID The ID of the dispute. 80 | */ 81 | function getAppealDisputeID(uint _disputeID) external view returns(uint disputeID) { 82 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) 83 | disputeID = AppealableArbitrator(address(appealDisputes[_disputeID].arbitrator)).getAppealDisputeID(appealDisputes[_disputeID].appealDisputeID); 84 | else disputeID = _disputeID; 85 | } 86 | 87 | /* Public */ 88 | 89 | /** @dev Appeals a ruling. 90 | * @param _disputeID The ID of the dispute. 91 | * @param _extraData Additional info about the appeal. 92 | */ 93 | function appeal(uint _disputeID, bytes memory _extraData) public payable requireAppealFee(_disputeID, _extraData) { 94 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) 95 | appealDisputes[_disputeID].arbitrator.appeal.value(msg.value)(appealDisputes[_disputeID].appealDisputeID, _extraData); 96 | else { 97 | appealDisputes[_disputeID].arbitrator = arbitrator; 98 | appealDisputes[_disputeID].appealDisputeID = arbitrator.createDispute.value(msg.value)(disputes[_disputeID].choices, _extraData); 99 | appealDisputeIDsToDisputeIDs[appealDisputes[_disputeID].appealDisputeID] = _disputeID; 100 | } 101 | } 102 | 103 | /** @dev Gives a ruling. 104 | * @param _disputeID The ID of the dispute. 105 | * @param _ruling The ruling. 106 | */ 107 | function giveRuling(uint _disputeID, uint _ruling) public { 108 | require(disputes[_disputeID].status != DisputeStatus.Solved, "The specified dispute is already resolved."); 109 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) { 110 | require(IArbitrator(msg.sender) == appealDisputes[_disputeID].arbitrator, "Appealed disputes must be ruled by their back up arbitrator."); 111 | super._giveRuling(_disputeID, _ruling); 112 | } else { 113 | require(msg.sender == owner, "Not appealed disputes must be ruled by the owner."); 114 | if (disputes[_disputeID].status == DisputeStatus.Appealable) { 115 | if (now - appealDisputes[_disputeID].rulingTime > timeOut) 116 | super._giveRuling(_disputeID, disputes[_disputeID].ruling); 117 | else revert("Time out time has not passed yet."); 118 | } else { 119 | disputes[_disputeID].ruling = _ruling; 120 | disputes[_disputeID].status = DisputeStatus.Appealable; 121 | appealDisputes[_disputeID].rulingTime = now; 122 | emit AppealPossible(_disputeID, disputes[_disputeID].arbitrated); 123 | } 124 | } 125 | } 126 | 127 | /** @dev Give a ruling for a dispute. Must be called by the arbitrator. 128 | * The purpose of this function is to ensure that the address calling it has the right to rule on the contract. 129 | * @param _disputeID ID of the dispute in the IArbitrator contract. 130 | * @param _ruling Ruling given by the arbitrator. Note that 0 is reserved for "Not able/wanting to make a decision". 131 | */ 132 | function rule(uint _disputeID, uint _ruling) public onlyArbitrator { 133 | emit Ruling(IArbitrator(msg.sender),_disputeID,_ruling); 134 | 135 | executeRuling(_disputeID,_ruling); 136 | } 137 | 138 | /* Public Views */ 139 | 140 | /** @dev Gets the cost of appeal for the specified dispute. 141 | * @param _disputeID The ID of the dispute. 142 | * @param _extraData Additional info about the appeal. 143 | * @return The cost of the appeal. 144 | */ 145 | function appealCost(uint _disputeID, bytes memory _extraData) public view returns(uint cost) { 146 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) 147 | cost = appealDisputes[_disputeID].arbitrator.appealCost(appealDisputes[_disputeID].appealDisputeID, _extraData); 148 | else if (disputes[_disputeID].status == DisputeStatus.Appealable) cost = arbitrator.arbitrationCost(_extraData); 149 | else cost = NOT_PAYABLE_VALUE; 150 | } 151 | 152 | /** @dev Gets the status of the specified dispute. 153 | * @param _disputeID The ID of the dispute. 154 | * @return The status. 155 | */ 156 | function disputeStatus(uint _disputeID) public view returns(DisputeStatus status) { 157 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) 158 | status = appealDisputes[_disputeID].arbitrator.disputeStatus(appealDisputes[_disputeID].appealDisputeID); 159 | else status = disputes[_disputeID].status; 160 | } 161 | 162 | /** @dev Return the ruling of a dispute. 163 | * @param _disputeID ID of the dispute to rule. 164 | * @return ruling The ruling which would or has been given. 165 | */ 166 | function currentRuling(uint _disputeID) public view returns(uint ruling) { 167 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) // Appealed. 168 | ruling = appealDisputes[_disputeID].arbitrator.currentRuling(appealDisputes[_disputeID].appealDisputeID); // Retrieve ruling from the arbitrator whom the dispute is appealed to. 169 | else ruling = disputes[_disputeID].ruling; // Not appealed, basic case. 170 | } 171 | 172 | /* Internal */ 173 | 174 | /** @dev Executes the ruling of the specified dispute. 175 | * @param _disputeID The ID of the dispute. 176 | * @param _ruling The ruling. 177 | */ 178 | function executeRuling(uint _disputeID, uint _ruling) internal { 179 | require( 180 | appealDisputes[appealDisputeIDsToDisputeIDs[_disputeID]].arbitrator != IArbitrator(address(0)), 181 | "The dispute must have been appealed." 182 | ); 183 | giveRuling(appealDisputeIDsToDisputeIDs[_disputeID], _ruling); 184 | } 185 | } -------------------------------------------------------------------------------- /contracts/test-purposes/CentralizedArbitrator.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@clesaege, @n1c01a5, @epiqueras, @ferittuncer, @unknownunknown1, @mtsalenc] 3 | * @reviewers: [@clesaege*, @unknownunknown1*] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.11; 10 | 11 | import { IArbitrator, IArbitrable } from "@kleros/erc-792/contracts/IArbitrator.sol"; 12 | 13 | /** @title Centralized Arbitrator 14 | * @dev This is a centralized arbitrator deciding alone on the result of disputes. No appeals are possible. 15 | */ 16 | contract CentralizedArbitrator is IArbitrator { 17 | 18 | address public owner = msg.sender; 19 | uint arbitrationPrice; // Not public because arbitrationCost already acts as an accessor. 20 | uint constant NOT_PAYABLE_VALUE = (2**256-2)/2; // High value to be sure that the appeal is too expensive. 21 | 22 | struct DisputeStruct { 23 | IArbitrable arbitrated; 24 | uint choices; 25 | uint fee; 26 | uint ruling; 27 | DisputeStatus status; 28 | } 29 | 30 | modifier onlyOwner {require(msg.sender==owner, "Can only be called by the owner."); _;} 31 | modifier requireArbitrationFee(bytes memory _extraData) { 32 | require(msg.value >= arbitrationCost(_extraData), "Not enough ETH to cover arbitration costs."); 33 | _; 34 | } 35 | 36 | DisputeStruct[] public disputes; 37 | 38 | /** @dev Constructor. Set the initial arbitration price. 39 | * @param _arbitrationPrice Amount to be paid for arbitration. 40 | */ 41 | constructor(uint _arbitrationPrice) public { 42 | arbitrationPrice = _arbitrationPrice; 43 | } 44 | 45 | /** @dev Set the arbitration price. Only callable by the owner. 46 | * @param _arbitrationPrice Amount to be paid for arbitration. 47 | */ 48 | function setArbitrationPrice(uint _arbitrationPrice) public onlyOwner { 49 | arbitrationPrice = _arbitrationPrice; 50 | } 51 | 52 | /** @dev Cost of arbitration. Accessor to arbitrationPrice. 53 | * @param _extraData Not used by this contract. 54 | * @return fee Amount to be paid. 55 | */ 56 | function arbitrationCost(bytes memory _extraData) public view returns(uint fee) { 57 | return arbitrationPrice; 58 | } 59 | 60 | /** @dev Cost of appeal. Since it is not possible, it's a high value which can never be paid. 61 | * @param _disputeID ID of the dispute to be appealed. Not used by this contract. 62 | * @param _extraData Not used by this contract. 63 | * @return fee Amount to be paid. 64 | */ 65 | function appealCost(uint _disputeID, bytes memory _extraData) public view returns(uint fee) { 66 | return NOT_PAYABLE_VALUE; 67 | } 68 | 69 | /** @dev Create a dispute. Must be called by the arbitrable contract. 70 | * Must be paid at least arbitrationCost(). 71 | * @param _choices Amount of choices the arbitrator can make in this dispute. When ruling ruling<=choices. 72 | * @param _extraData Can be used to give additional info on the dispute to be created. 73 | * @return disputeID ID of the dispute created. 74 | */ 75 | function createDispute(uint _choices, bytes memory _extraData) public payable requireArbitrationFee(_extraData) returns(uint disputeID) { 76 | disputeID = disputes.push(DisputeStruct({ 77 | arbitrated: IArbitrable(msg.sender), 78 | choices: _choices, 79 | fee: msg.value, 80 | ruling: 0, 81 | status: DisputeStatus.Waiting 82 | })) - 1; // Create the dispute and return its number. 83 | emit DisputeCreation(disputeID, IArbitrable(msg.sender)); 84 | } 85 | 86 | /** @dev Give a ruling. UNTRUSTED. 87 | * @param _disputeID ID of the dispute to rule. 88 | * @param _ruling Ruling given by the arbitrator. Note that 0 means "Not able/wanting to make a decision". 89 | */ 90 | function _giveRuling(uint _disputeID, uint _ruling) internal { 91 | DisputeStruct storage dispute = disputes[_disputeID]; 92 | require(_ruling <= dispute.choices, "Invalid ruling."); 93 | require(dispute.status != DisputeStatus.Solved, "The dispute must not be solved already."); 94 | 95 | dispute.ruling = _ruling; 96 | dispute.status = DisputeStatus.Solved; 97 | 98 | msg.sender.send(dispute.fee); // Avoid blocking. 99 | dispute.arbitrated.rule(_disputeID,_ruling); 100 | } 101 | 102 | /** @dev Give a ruling. UNTRUSTED. 103 | * @param _disputeID ID of the dispute to rule. 104 | * @param _ruling Ruling given by the arbitrator. Note that 0 means "Not able/wanting to make a decision". 105 | */ 106 | function giveRuling(uint _disputeID, uint _ruling) public onlyOwner { 107 | return _giveRuling(_disputeID, _ruling); 108 | } 109 | 110 | /** @dev Return the status of a dispute. 111 | * @param _disputeID ID of the dispute to rule. 112 | * @return status The status of the dispute. 113 | */ 114 | function disputeStatus(uint _disputeID) public view returns(DisputeStatus status) { 115 | return disputes[_disputeID].status; 116 | } 117 | 118 | /** @dev Return the ruling of a dispute. 119 | * @param _disputeID ID of the dispute to rule. 120 | * @return ruling The ruling which would or has been given. 121 | */ 122 | function currentRuling(uint _disputeID) public view returns(uint ruling) { 123 | return disputes[_disputeID].ruling; 124 | } 125 | } -------------------------------------------------------------------------------- /contracts/test-purposes/EnhancedAppealableArbitrator.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@epiqueras, @unknownunknown1, @mtsalenc] 3 | * @reviewers: [] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.11; 10 | 11 | import "./AppealableArbitrator.sol"; 12 | 13 | /** 14 | * @title EnhancedAppealableArbitrator 15 | * @author Enrique Piqueras - 16 | * @dev Implementation of `AppealableArbitrator` that supports `appealPeriod`. 17 | */ 18 | contract EnhancedAppealableArbitrator is AppealableArbitrator { 19 | /* Constructor */ 20 | 21 | /* solium-disable no-empty-blocks */ 22 | /** @dev Constructs the `EnhancedAppealableArbitrator` contract. 23 | * @param _arbitrationPrice The amount to be paid for arbitration. 24 | * @param _arbitrator The back up arbitrator. 25 | * @param _arbitratorExtraData Not used by this contract. 26 | * @param _timeOut The time out for the appeal period. 27 | */ 28 | constructor( 29 | uint256 _arbitrationPrice, 30 | IArbitrator _arbitrator, 31 | bytes memory _arbitratorExtraData, 32 | uint256 _timeOut 33 | ) public AppealableArbitrator(_arbitrationPrice, _arbitrator, _arbitratorExtraData, _timeOut) {} 34 | 35 | /* solium-enable no-empty-blocks */ 36 | 37 | /* Public Views */ 38 | 39 | /** @dev Compute the start and end of the dispute's current or next appeal period, if possible. 40 | * @param _disputeID ID of the dispute. 41 | * @return The start and end of the period. 42 | */ 43 | function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) { 44 | if (appealDisputes[_disputeID].arbitrator != IArbitrator(address(0))) 45 | (start, end) = appealDisputes[_disputeID].arbitrator.appealPeriod( 46 | appealDisputes[_disputeID].appealDisputeID 47 | ); 48 | else { 49 | start = appealDisputes[_disputeID].rulingTime; 50 | require(start != 0, "The specified dispute is not appealable."); 51 | end = start + timeOut; 52 | } 53 | } 54 | 55 | /** @dev Appeals a ruling. 56 | * @param _disputeID The ID of the dispute. 57 | * @param _extraData Additional info about the appeal. 58 | */ 59 | function appeal(uint256 _disputeID, bytes memory _extraData) 60 | public 61 | payable 62 | requireAppealFee(_disputeID, _extraData) 63 | { 64 | emit AppealDecision(_disputeID, IArbitrable(msg.sender)); 65 | return super.appeal(_disputeID, _extraData); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /contracts/test-purposes/RelayMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.16; 2 | 3 | import "../LightGeneralizedTCR.sol"; 4 | 5 | contract RelayMock { 6 | function add(LightGeneralizedTCR _gtcr, string calldata _itemData) 7 | external 8 | { 9 | _gtcr.addItemDirectly(_itemData); 10 | } 11 | 12 | function remove(LightGeneralizedTCR _gtcr, bytes32 _itemID) external { 13 | _gtcr.removeItemDirectly(_itemID); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /contracts/utils/CappedMath.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc*] 3 | * @reviewers: [@clesaege*] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity ^0.5.16; 10 | 11 | /** 12 | * @title CappedMath 13 | * @dev Math operations with caps for under and overflow. 14 | */ 15 | library CappedMath { 16 | uint256 private constant UINT_MAX = 2**256 - 1; 17 | 18 | /** 19 | * @dev Adds two unsigned integers, returns 2^256 - 1 on overflow. 20 | */ 21 | function addCap(uint256 _a, uint256 _b) internal pure returns (uint256) { 22 | uint256 c = _a + _b; 23 | return c >= _a ? c : UINT_MAX; 24 | } 25 | 26 | /** 27 | * @dev Subtracts two integers, returns 0 on underflow. 28 | */ 29 | function subCap(uint256 _a, uint256 _b) internal pure returns (uint256) { 30 | if (_b > _a) return 0; 31 | else return _a - _b; 32 | } 33 | 34 | /** 35 | * @dev Multiplies two unsigned integers, returns 2^256 - 1 on overflow. 36 | */ 37 | function mulCap(uint256 _a, uint256 _b) internal pure returns (uint256) { 38 | // Gas optimization: this is cheaper than requiring '_a' not being zero, but the 39 | // benefit is lost if '_b' is also tested. 40 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 41 | if (_a == 0) return 0; 42 | 43 | uint256 c = _a * _b; 44 | return c / _a == _b ? c : UINT_MAX; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/utils/CappedMath128.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@hbarcelos] 3 | * @reviewers: [@fnanni-0] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | pragma solidity ^0.5.16; 9 | 10 | /** 11 | * @title CappedMath 12 | * @dev Math operations with caps for under and overflow. 13 | */ 14 | library CappedMath128 { 15 | uint128 private constant UINT128_MAX = 2**128 - 1; 16 | 17 | /** 18 | * @dev Adds two unsigned integers, returns 2^128 - 1 on overflow. 19 | */ 20 | function addCap(uint128 _a, uint128 _b) internal pure returns (uint128) { 21 | uint128 c = _a + _b; 22 | return c >= _a ? c : UINT128_MAX; 23 | } 24 | 25 | /** 26 | * @dev Subtracts two integers, returns 0 on underflow. 27 | */ 28 | function subCap(uint128 _a, uint128 _b) internal pure returns (uint128) { 29 | if (_b > _a) return 0; 30 | else return _a - _b; 31 | } 32 | 33 | /** 34 | * @dev Multiplies two unsigned integers, returns 2^128 - 1 on overflow. 35 | */ 36 | function mulCap(uint128 _a, uint128 _b) internal pure returns (uint128) { 37 | if (_a == 0) return 0; 38 | 39 | uint128 c = _a * _b; 40 | return c / _a == _b ? c : UINT128_MAX; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/view/GeneralizedTCRView.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc] 3 | * @reviewers: [] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity 0.5.17; 10 | pragma experimental ABIEncoderV2; 11 | 12 | import { GeneralizedTCR, IArbitrator } from "../GeneralizedTCR.sol"; 13 | import { BytesLib } from "solidity-bytes-utils/contracts/BytesLib.sol"; 14 | import { RLPReader } from "solidity-rlp/contracts/RLPReader.sol"; 15 | 16 | /* solium-disable max-len */ 17 | /* solium-disable security/no-block-members */ 18 | /* solium-disable security/no-send */ // It is the user responsibility to accept ETH. 19 | 20 | /** 21 | * @title GeneralizedTCRView 22 | * A view contract to fetch, batch, parse and return GTCR contract data efficiently. 23 | * This contract includes functions that can halt execution due to out-of-gas exceptions. Because of this it should never be relied upon by other contracts. 24 | */ 25 | contract GeneralizedTCRView { 26 | using RLPReader for RLPReader.RLPItem; 27 | using RLPReader for bytes; 28 | using BytesLib for bytes; 29 | 30 | struct QueryResult { 31 | bytes32 ID; 32 | bytes data; 33 | GeneralizedTCR.Status status; 34 | bool disputed; 35 | bool resolved; 36 | uint disputeID; 37 | uint appealCost; 38 | bool appealed; 39 | uint appealStart; 40 | uint appealEnd; 41 | GeneralizedTCR.Party ruling; 42 | address requester; 43 | address challenger; 44 | address arbitrator; 45 | bytes arbitratorExtraData; 46 | GeneralizedTCR.Party currentRuling; 47 | bool[3] hasPaid; 48 | uint feeRewards; 49 | uint submissionTime; 50 | uint[3] amountPaid; 51 | IArbitrator.DisputeStatus disputeStatus; 52 | uint numberOfRequests; 53 | } 54 | 55 | struct ArbitrableData { 56 | address governor; 57 | address arbitrator; 58 | bytes arbitratorExtraData; 59 | uint submissionBaseDeposit; 60 | uint removalBaseDeposit; 61 | uint submissionChallengeBaseDeposit; 62 | uint removalChallengeBaseDeposit; 63 | uint challengePeriodDuration; 64 | uint metaEvidenceUpdates; 65 | uint winnerStakeMultiplier; 66 | uint loserStakeMultiplier; 67 | uint sharedStakeMultiplier; 68 | uint MULTIPLIER_DIVISOR; 69 | uint arbitrationCost; 70 | } 71 | 72 | /** @dev Fetch arbitrable TCR data in a single call. 73 | * @param _address The address of the Generalized TCR to query. 74 | * @return The latest data on an arbitrable TCR contract. 75 | */ 76 | function fetchArbitrable(address _address) external view returns (ArbitrableData memory result) { 77 | GeneralizedTCR tcr = GeneralizedTCR(_address); 78 | result.governor = tcr.governor(); 79 | result.arbitrator = address(tcr.arbitrator()); 80 | result.arbitratorExtraData = tcr.arbitratorExtraData(); 81 | result.submissionBaseDeposit = tcr.submissionBaseDeposit(); 82 | result.removalBaseDeposit = tcr.removalBaseDeposit(); 83 | result.submissionChallengeBaseDeposit = tcr.submissionChallengeBaseDeposit(); 84 | result.removalChallengeBaseDeposit = tcr.removalChallengeBaseDeposit(); 85 | result.challengePeriodDuration = tcr.challengePeriodDuration(); 86 | result.metaEvidenceUpdates = tcr.metaEvidenceUpdates(); 87 | result.winnerStakeMultiplier = tcr.winnerStakeMultiplier(); 88 | result.loserStakeMultiplier = tcr.loserStakeMultiplier(); 89 | result.sharedStakeMultiplier = tcr.sharedStakeMultiplier(); 90 | result.MULTIPLIER_DIVISOR = tcr.MULTIPLIER_DIVISOR(); 91 | result.arbitrationCost = IArbitrator(result.arbitrator).arbitrationCost(result.arbitratorExtraData); 92 | } 93 | 94 | /** @dev Fetch the latest data on an item in a single call. 95 | * @param _address The address of the Generalized TCR to query. 96 | * @param _itemID The ID of the item to query. 97 | * @return The item data. 98 | */ 99 | function getItem(address _address, bytes32 _itemID) public view returns (QueryResult memory result) { 100 | RoundData memory round = getLatestRoundRequestData(_address, _itemID); 101 | result = QueryResult({ 102 | ID: _itemID, 103 | data: round.request.item.data, 104 | status: round.request.item.status, 105 | disputed: round.request.disputed, 106 | resolved: round.request.resolved, 107 | disputeID: round.request.disputeID, 108 | appealCost: 0, 109 | appealed: round.appealed, 110 | appealStart: 0, 111 | appealEnd: 0, 112 | ruling: round.request.ruling, 113 | requester: round.request.parties[uint(GeneralizedTCR.Party.Requester)], 114 | challenger: round.request.parties[uint(GeneralizedTCR.Party.Challenger)], 115 | arbitrator: address(round.request.arbitrator), 116 | arbitratorExtraData: round.request.arbitratorExtraData, 117 | currentRuling: GeneralizedTCR.Party.None, 118 | hasPaid: round.hasPaid, 119 | feeRewards: round.feeRewards, 120 | submissionTime: round.request.submissionTime, 121 | amountPaid: round.amountPaid, 122 | disputeStatus: IArbitrator.DisputeStatus.Waiting, 123 | numberOfRequests: round.request.item.numberOfRequests 124 | }); 125 | if (round.request.disputed && round.request.arbitrator.disputeStatus(result.disputeID) == IArbitrator.DisputeStatus.Appealable) { 126 | result.currentRuling = GeneralizedTCR.Party(round.request.arbitrator.currentRuling(result.disputeID)); 127 | result.disputeStatus = round.request.arbitrator.disputeStatus(result.disputeID); 128 | (result.appealStart, result.appealEnd) = round.request.arbitrator.appealPeriod(result.disputeID); 129 | result.appealCost = round.request.arbitrator.appealCost(result.disputeID, result.arbitratorExtraData); 130 | } 131 | } 132 | 133 | struct ItemRequest { 134 | bool disputed; 135 | uint disputeID; 136 | uint submissionTime; 137 | bool resolved; 138 | address requester; 139 | address challenger; 140 | address arbitrator; 141 | bytes arbitratorExtraData; 142 | uint metaEvidenceID; 143 | } 144 | 145 | /** @dev Fetch all requests for an item. 146 | * @param _address The address of the Generalized TCR to query. 147 | * @param _itemID The ID of the item to query. 148 | * @return The items requests. 149 | */ 150 | function getItemRequests(address _address, bytes32 _itemID) external view returns (ItemRequest[] memory requests) { 151 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 152 | ItemData memory itemData = getItemData(_address, _itemID); 153 | requests = new ItemRequest[](itemData.numberOfRequests); 154 | for (uint i = 0; i < itemData.numberOfRequests; i++) { 155 | ( 156 | bool disputed, 157 | uint disputeID, 158 | uint submissionTime, 159 | bool resolved, 160 | address payable[3] memory parties, 161 | , 162 | , 163 | IArbitrator arbitrator, 164 | bytes memory arbitratorExtraData, 165 | uint metaEvidenceID 166 | ) = gtcr.getRequestInfo(_itemID, i); 167 | 168 | // Sort requests by newest first. 169 | requests[itemData.numberOfRequests - i - 1] = ItemRequest({ 170 | disputed: disputed, 171 | disputeID: disputeID, 172 | submissionTime: submissionTime, 173 | resolved: resolved, 174 | requester: parties[uint(GeneralizedTCR.Party.Requester)], 175 | challenger: parties[uint(GeneralizedTCR.Party.Challenger)], 176 | arbitrator: address(arbitrator), 177 | arbitratorExtraData: arbitratorExtraData, 178 | metaEvidenceID: metaEvidenceID 179 | }); 180 | } 181 | } 182 | 183 | /** @dev Find an item by matching column values exactly. Unless specified in the _ignoreColumns parameter, finding an item requires matching all columns. 184 | * - Example: 185 | * Item [18, 'PNK', 'Pinakion', '0xca35b7d915458ef540ade6068dfe2f44e8fa733c'] 186 | * RLP encoded: 0xe383504e4b128850696e616b696f6e94ca35b7d915458ef540ade6068dfe2f44e8fa733c 187 | * Input for remix: ["0xe3","0x83","0x50","0x4e","0x4b","0x12","0x88","0x50","0x69","0x6e","0x61","0x6b","0x69","0x6f","0x6e","0x94","0xca","0x35","0xb7","0xd9","0x15","0x45","0x8e","0xf5","0x40","0xad","0xe6","0x06","0x8d","0xfe","0x2f","0x44","0xe8","0xfa","0x73","0x3c"] 188 | * @param _address The address of the Generalized TCR to query. 189 | * @param _rlpEncodedMatch The RLP encoded item to match against the items on the list. 190 | * @param _cursor The index from where to start looking for matches. 191 | * @param _count The number of items to iterate and return while searching. 192 | * @param _skipState Boolean tuple defining whether to skip items in a given state. [Absent, Registered, RegistrationRequested, ClearingRequested]. 193 | * @param _ignoreColumns Columns to ignore when searching. If this is an array with only false items, then every column must match exactly. 194 | * @return An array with items that match the query. 195 | */ 196 | function findItem( 197 | address _address, 198 | bytes memory _rlpEncodedMatch, 199 | uint _cursor, 200 | uint _count, 201 | bool[4] memory _skipState, 202 | bool[] memory _ignoreColumns 203 | ) 204 | public 205 | view 206 | returns (QueryResult[] memory results) 207 | { 208 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 209 | RLPReader.RLPItem[] memory matchItem = _rlpEncodedMatch.toRlpItem().toList(); 210 | results = new QueryResult[](_count == 0 ? gtcr.itemCount() : _count); 211 | uint itemsFound; 212 | 213 | for(uint i = _cursor; i < (_count == 0 ? gtcr.itemCount() : _count); i++) { // Iterate over every item in storage. 214 | QueryResult memory item = getItem(_address, gtcr.itemList(i)); 215 | if (_skipState[uint(item.status)]) 216 | continue; 217 | 218 | RLPReader.RLPItem[] memory itemData = item.data.toRlpItem().toList(); 219 | bool itemFound = true; 220 | for (uint j = 0; j < matchItem.length; j++) { // Iterate over every column. 221 | if (!_ignoreColumns[j] && !itemData[j].toBytes().equal(matchItem[j].toBytes())) { 222 | // This column should not be ignored and it did not match input. Item not found. 223 | itemFound = false; 224 | break; 225 | } 226 | } 227 | 228 | // All not ignored columns matched, item found. Add it 229 | if (itemFound) { 230 | results[itemsFound] = item; 231 | itemsFound++; 232 | } 233 | } 234 | 235 | return results; 236 | } 237 | 238 | /** @dev Find the index of the first item of a page of items for a given filter. 239 | * @param _address The address of the Generalized TCR to query. 240 | * @param _targets The targets to use for the query. Each element of the array in sequence means: 241 | * - The page to search; 242 | * - The number of items per page; 243 | * - The number of items to iterate when searching; 244 | * - The position from where to start iterating. 245 | * @param _filter The filter to use. Each element of the array in sequence means: 246 | * - Include absent items in result; 247 | * - Include registered items in result; 248 | * - Include items with registration requests that are not disputed in result; 249 | * - Include items with clearing requests that are not disputed in result; 250 | * - Include disputed items with registration requests in result; 251 | * - Include disputed items with clearing requests in result; 252 | * - Include items with a request by _party; 253 | * - Include items challenged by _party. 254 | * - Whether to sort from oldest to the newest item. 255 | * @param _party The address to use if checking for items with a request or challenged by a specific party. 256 | * @return The query result: 257 | * - Index of the page, if it was found; 258 | * - Whether there are more items to iterate; 259 | * - If the index of the page we are searching was found. 260 | */ 261 | function findIndexForPage( 262 | address _address, 263 | uint[4] calldata _targets, 264 | bool[9] calldata _filter, 265 | address _party 266 | ) 267 | external 268 | view 269 | returns (uint index, bool hasMore, bool indexFound) 270 | { 271 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 272 | uint count = _targets[2]; 273 | uint currPage = 1; 274 | uint itemsMatched = 0; 275 | 276 | if (gtcr.itemCount() == 0) return (0, false, true); 277 | 278 | // Start iterating from the end if the _cursorIndex is 0 and _oldestFirst is false. 279 | // Keep the cursor as is otherwise. 280 | uint i = _filter[8] ? _targets[3] : _targets[3] == 0 ? gtcr.itemCount() - 1 : _targets[3]; 281 | 282 | for(; _filter[8] ? i < gtcr.itemCount() && count > 0 : i >= 0 && count > 0; ) { 283 | bytes32 itemID = gtcr.itemList(i); 284 | QueryResult memory item = getItem(_address, itemID); 285 | hasMore = true; 286 | if ( 287 | (_filter[0] && item.status == GeneralizedTCR.Status.Absent) || 288 | (_filter[1] && item.status == GeneralizedTCR.Status.Registered) || 289 | (_filter[2] && item.status == GeneralizedTCR.Status.RegistrationRequested && !item.disputed) || 290 | (_filter[3] && item.status == GeneralizedTCR.Status.ClearingRequested && !item.disputed) || 291 | (_filter[4] && item.status == GeneralizedTCR.Status.RegistrationRequested && item.disputed) || 292 | (_filter[5] && item.status == GeneralizedTCR.Status.ClearingRequested && item.disputed) || 293 | (_filter[6] && item.requester == _party) || 294 | (_filter[7] && item.challenger == _party) 295 | ) { 296 | itemsMatched++; 297 | if (itemsMatched % _targets[1] == 0) { 298 | currPage++; 299 | if (currPage == _targets[0]){ 300 | if ((i == 0 && !_filter[8]) || (i == gtcr.itemCount() - 1 && _filter[8])) hasMore = false; 301 | return (_filter[8] ? i + 1 : i - 1, hasMore, true); 302 | } 303 | } 304 | } 305 | count--; 306 | if (count == 0 || (i == 0 && !_filter[8]) || (i == gtcr.itemCount() - 1 && _filter[8])) { 307 | hasMore = _filter[8] ? i < gtcr.itemCount() : i > 0; 308 | break; 309 | } 310 | // Move cursor to the left or right depending on _oldestFirst. 311 | // Also prevents underflow if the cursor is at the first item. 312 | i = _filter[8] ? i + 1 : i == 0 ? 0 : i - 1; 313 | } 314 | 315 | // If sorting by oldest first, and not enough items were found to fill a page, return the cursor index. 316 | if (_filter[8] && _targets[3] + _targets[1] > _targets[3] + i) { 317 | i = _targets[3]; 318 | } 319 | return (i, hasMore, false); 320 | } 321 | 322 | /** @dev Count the number of items for a given filter. 323 | * @param _address The address of the Generalized TCR to query. 324 | * @param _cursorIndex The index of the items from which to start iterating. To start from either the oldest or newest item. 325 | * @param _count The number of items to return. 326 | * @param _filter The filter to use. Each element of the array in sequence means: 327 | * - Include absent items in result; 328 | * - Include registered items in result; 329 | * - Include items with registration requests that are not disputed in result; 330 | * - Include items with clearing requests that are not disputed in result; 331 | * - Include disputed items with registration requests in result; 332 | * - Include disputed items with clearing requests in result; 333 | * - Include items with a request by _party; 334 | * - Include items challenged by _party. 335 | * @param _party The address to use if checking for items with a request or challenged by a specific party. 336 | * @return The query result: 337 | * - The number of items found for the filter; 338 | * - Whether there are more items to iterate; 339 | * - The index of the last item of the query. Useful as a starting point for the next query if counting in multiple steps. 340 | */ 341 | function countWithFilter(address _address, uint _cursorIndex, uint _count, bool[8] calldata _filter, address _party) 342 | external 343 | view 344 | returns (uint count, bool hasMore, uint) 345 | { 346 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 347 | if (gtcr.itemCount() == 0) return (0, false, 0); 348 | 349 | uint iterations = 0; 350 | for (uint i = _cursorIndex; iterations <= _count && i < gtcr.itemCount(); i++) { 351 | bytes32 itemID = gtcr.itemList(i); 352 | QueryResult memory item = getItem(_address, itemID); 353 | if ( 354 | (_filter[0] && item.status == GeneralizedTCR.Status.Absent) || 355 | (_filter[1] && item.status == GeneralizedTCR.Status.Registered) || 356 | (_filter[2] && item.status == GeneralizedTCR.Status.RegistrationRequested && !item.disputed) || 357 | (_filter[3] && item.status == GeneralizedTCR.Status.ClearingRequested && !item.disputed) || 358 | (_filter[4] && item.status == GeneralizedTCR.Status.RegistrationRequested && item.disputed) || 359 | (_filter[5] && item.status == GeneralizedTCR.Status.ClearingRequested && item.disputed) || 360 | (_filter[6] && item.requester == _party) || 361 | (_filter[7] && item.challenger == _party) 362 | ) { 363 | count++; 364 | if (iterations >= _count) { 365 | return (count, true, i); 366 | } 367 | } 368 | iterations++; 369 | } 370 | } 371 | 372 | /** @dev Return the values of the items the query finds. This function is O(n), where n is the number of items. This could exceed the gas limit, therefore this function should only be used for interface display and not by other contracts. 373 | * @param _address The address of the GTCR to query. 374 | * @param _cursorIndex The index of the items from which to start iterating. To start from either the oldest or newest item. 375 | * @param _count The number of items to iterate. 376 | * @param _filter The filter to use. Each element of the array in sequence means: 377 | * - Include absent items in result; 378 | * - Include registered items in result; 379 | * - Include items with registration requests that are not disputed in result; 380 | * - Include items with clearing requests that are not disputed in result; 381 | * - Include disputed items with registration requests in result; 382 | * - Include disputed items with clearing requests in result; 383 | * - Include items with a request by _party; 384 | * - Include items challenged by _party. 385 | * @param _oldestFirst Whether to sort from oldest to the newest item. 386 | * @param _party The address to use if checking for items with a request or challenged by a specific party. 387 | * @param _limit The maximum number of items to return. If set to 0 will return _count items. 388 | * @return The data of the items found and whether there are more items for the current filter and sort. 389 | */ 390 | function queryItems( 391 | address _address, 392 | uint _cursorIndex, 393 | uint _count, 394 | bool[8] calldata _filter, 395 | bool _oldestFirst, 396 | address _party, 397 | uint _limit 398 | ) 399 | external 400 | view 401 | returns (QueryResult[] memory results, bool hasMore) 402 | { 403 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 404 | results = new QueryResult[](_count); 405 | uint index = 0; 406 | uint count = _count; 407 | if (_limit == 0) _limit = count; 408 | 409 | if (gtcr.itemCount() == 0) return (results, false); 410 | 411 | // Start iterating from the end if the _cursorIndex is 0 and _oldestFirst is false. 412 | // Keep the cursor as is otherwise. 413 | uint i = _oldestFirst ? _cursorIndex : _cursorIndex == 0 ? gtcr.itemCount() - 1 : _cursorIndex; 414 | 415 | for(; _oldestFirst ? i < gtcr.itemCount() && count > 0 : i >= 0 && count > 0; ) { 416 | bytes32 itemID = gtcr.itemList(i); 417 | QueryResult memory item = getItem(_address, itemID); 418 | hasMore = true; 419 | if ( 420 | (_filter[0] && item.status == GeneralizedTCR.Status.Absent) || 421 | (_filter[1] && item.status == GeneralizedTCR.Status.Registered) || 422 | (_filter[2] && item.status == GeneralizedTCR.Status.RegistrationRequested && !item.disputed) || 423 | (_filter[3] && item.status == GeneralizedTCR.Status.ClearingRequested && !item.disputed) || 424 | (_filter[4] && item.status == GeneralizedTCR.Status.RegistrationRequested && item.disputed) || 425 | (_filter[5] && item.status == GeneralizedTCR.Status.ClearingRequested && item.disputed) || 426 | (_filter[6] && item.requester == _party) || 427 | (_filter[7] && item.challenger == _party) 428 | ) { 429 | results[index] = item; 430 | index++; 431 | if (index == _limit) break; 432 | } 433 | count--; 434 | if (count == 0 || (i == 0 && !_oldestFirst) || (i == gtcr.itemCount() - 1 && _oldestFirst)) { 435 | hasMore = _oldestFirst ? i < gtcr.itemCount() - 1 : i > 0; 436 | break; 437 | } 438 | // Move cursor to the left or right depending on _oldestFirst. 439 | // Also prevents underflow if the cursor is at the first item. 440 | i = _oldestFirst ? i + 1 : i == 0 ? 0 : i - 1; 441 | } 442 | } 443 | 444 | /** @dev Return the withdrawable rewards for a contributor. 445 | * @param _address The address of the Generalized TCR to query. 446 | * @param _itemID The ID of the item to query. 447 | * @param _contributor The address of the contributor. 448 | * @return The amount withdrawable per round per request. 449 | */ 450 | function availableRewards(address _address, bytes32 _itemID, address _contributor) external view returns (uint rewards) { 451 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 452 | 453 | // Using arrays to avoid stack limit. 454 | uint[2] memory requestRoundCount = [uint(0), uint(0)]; 455 | uint[2] memory indexes = [uint(0), uint(0)]; // Request index and round index. 456 | 457 | (,,requestRoundCount[0]) = gtcr.getItemInfo(_itemID); 458 | for (indexes[0]; indexes[0] < requestRoundCount[0]; indexes[0]++) { 459 | GeneralizedTCR.Party ruling; 460 | bool resolved; 461 | (,,, resolved,, requestRoundCount[1], ruling,,,) = gtcr.getRequestInfo(_itemID, indexes[0]); 462 | if (!resolved) continue; 463 | for (indexes[1]; indexes[1] < requestRoundCount[1]; indexes[1]++) { 464 | ( 465 | , 466 | uint[3] memory amountPaid, 467 | bool[3] memory hasPaid, 468 | uint feeRewards 469 | ) = gtcr.getRoundInfo(_itemID, indexes[0], indexes[1]); 470 | 471 | uint[3] memory roundContributions = gtcr.getContributions(_itemID, indexes[0], indexes[1], _contributor); 472 | if (!hasPaid[uint(GeneralizedTCR.Party.Requester)] || !hasPaid[uint(GeneralizedTCR.Party.Challenger)]) { 473 | // Amount reimbursable if not enough fees were raised to appeal the ruling. 474 | rewards += roundContributions[uint(GeneralizedTCR.Party.Requester)] + roundContributions[uint(GeneralizedTCR.Party.Challenger)]; 475 | } else if (ruling == GeneralizedTCR.Party.None) { 476 | // Reimbursable fees proportional if there aren't a winner and loser. 477 | rewards += amountPaid[uint(GeneralizedTCR.Party.Requester)] > 0 478 | ? (roundContributions[uint(GeneralizedTCR.Party.Requester)] * feeRewards) / (amountPaid[uint(GeneralizedTCR.Party.Challenger)] + amountPaid[uint(GeneralizedTCR.Party.Requester)]) 479 | : 0; 480 | rewards += amountPaid[uint(GeneralizedTCR.Party.Challenger)] > 0 481 | ? (roundContributions[uint(GeneralizedTCR.Party.Challenger)] * feeRewards) / (amountPaid[uint(GeneralizedTCR.Party.Challenger)] + amountPaid[uint(GeneralizedTCR.Party.Requester)]) 482 | : 0; 483 | } else { 484 | // Contributors to the winner take the rewards. 485 | rewards += amountPaid[uint(ruling)] > 0 486 | ? (roundContributions[uint(ruling)] * feeRewards) / amountPaid[uint(ruling)] 487 | : 0; 488 | } 489 | } 490 | indexes[1] = 0; 491 | } 492 | } 493 | 494 | 495 | // Functions and structs below used mainly to avoid stack limit. 496 | struct ItemData { 497 | bytes data; 498 | GeneralizedTCR.Status status; 499 | uint numberOfRequests; 500 | } 501 | 502 | struct RequestData { 503 | ItemData item; 504 | bool disputed; 505 | uint disputeID; 506 | uint submissionTime; 507 | bool resolved; 508 | address payable[3] parties; 509 | uint numberOfRounds; 510 | GeneralizedTCR.Party ruling; 511 | IArbitrator arbitrator; 512 | bytes arbitratorExtraData; 513 | } 514 | 515 | struct RoundData { 516 | RequestData request; 517 | bool appealed; 518 | uint[3] amountPaid; 519 | bool[3] hasPaid; 520 | uint feeRewards; 521 | } 522 | 523 | /** @dev Fetch data of the an item and return a struct. 524 | * @param _address The address of the Generalized TCR to query. 525 | * @param _itemID The ID of the item to query. 526 | * @return The round data. 527 | */ 528 | function getItemData(address _address, bytes32 _itemID) public view returns(ItemData memory item) { 529 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 530 | ( 531 | bytes memory data, 532 | GeneralizedTCR.Status status, 533 | uint numberOfRequests 534 | ) = gtcr.getItemInfo(_itemID); 535 | item = ItemData(data, status, numberOfRequests); 536 | } 537 | 538 | /** @dev Fetch the latest request of item. 539 | * @param _address The address of the Generalized TCR to query. 540 | * @param _itemID The ID of the item to query. 541 | * @return The round data. 542 | */ 543 | function getLatestRequestData(address _address, bytes32 _itemID) public view returns (RequestData memory request) { 544 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 545 | ItemData memory item = getItemData(_address, _itemID); 546 | ( 547 | bool disputed, 548 | uint disputeID, 549 | uint submissionTime, 550 | bool resolved, 551 | address payable[3] memory parties, 552 | uint numberOfRounds, 553 | GeneralizedTCR.Party ruling, 554 | IArbitrator arbitrator, 555 | bytes memory arbitratorExtraData, 556 | ) = gtcr.getRequestInfo(_itemID, item.numberOfRequests - 1); 557 | request = RequestData( 558 | item, 559 | disputed, 560 | disputeID, 561 | submissionTime, 562 | resolved, 563 | parties, 564 | numberOfRounds, 565 | ruling, 566 | arbitrator, 567 | arbitratorExtraData 568 | ); 569 | } 570 | 571 | /** @dev Fetch the latest round of the latest request of an item. 572 | * @param _address The address of the Generalized TCR to query. 573 | * @param _itemID The ID of the item to query. 574 | * @return The round data. 575 | */ 576 | function getLatestRoundRequestData(address _address, bytes32 _itemID) public view returns (RoundData memory round) { 577 | GeneralizedTCR gtcr = GeneralizedTCR(_address); 578 | RequestData memory request = getLatestRequestData(_address, _itemID); 579 | ( 580 | bool appealed, 581 | uint[3] memory amountPaid, 582 | bool[3] memory hasPaid, 583 | uint feeRewards 584 | ) = gtcr.getRoundInfo(_itemID, request.item.numberOfRequests - 1, request.numberOfRounds - 1); 585 | round = RoundData( 586 | request, 587 | appealed, 588 | amountPaid, 589 | hasPaid, 590 | feeRewards 591 | ); 592 | } 593 | } 594 | -------------------------------------------------------------------------------- /contracts/view/LightGeneralizedTCRView.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * @authors: [@mtsalenc] 3 | * @reviewers: [] 4 | * @auditors: [] 5 | * @bounties: [] 6 | * @deployments: [] 7 | */ 8 | 9 | pragma solidity 0.5.17; 10 | pragma experimental ABIEncoderV2; 11 | 12 | import {LightGeneralizedTCR, IArbitrator} from "../LightGeneralizedTCR.sol"; 13 | 14 | /* solium-disable max-len */ 15 | /* solium-disable security/no-block-members */ 16 | /* solium-disable security/no-send */ 17 | // It is the user responsibility to accept ETH. 18 | 19 | /** 20 | * @title LightGeneralizedTCRView 21 | * A view contract to fetch, batch, parse and return GTCR contract data efficiently. 22 | * This contract includes functions that can halt execution due to out-of-gas exceptions. Because of this it should never be relied upon by other contracts. 23 | */ 24 | contract LightGeneralizedTCRView { 25 | struct QueryResult { 26 | bytes32 ID; 27 | LightGeneralizedTCR.Status status; 28 | bool disputed; 29 | bool resolved; 30 | uint256 disputeID; 31 | uint256 appealCost; 32 | bool appealed; 33 | uint256 appealStart; 34 | uint256 appealEnd; 35 | LightGeneralizedTCR.Party ruling; 36 | address requester; 37 | address challenger; 38 | address arbitrator; 39 | bytes arbitratorExtraData; 40 | LightGeneralizedTCR.Party currentRuling; 41 | bool[3] hasPaid; 42 | uint256 feeRewards; 43 | uint256 submissionTime; 44 | uint256[3] amountPaid; 45 | IArbitrator.DisputeStatus disputeStatus; 46 | uint256 numberOfRequests; 47 | } 48 | 49 | struct ArbitrableData { 50 | address governor; 51 | address arbitrator; 52 | bytes arbitratorExtraData; 53 | uint256 submissionBaseDeposit; 54 | uint256 removalBaseDeposit; 55 | uint256 submissionChallengeBaseDeposit; 56 | uint256 removalChallengeBaseDeposit; 57 | uint256 challengePeriodDuration; 58 | uint256 metaEvidenceUpdates; 59 | uint256 winnerStakeMultiplier; 60 | uint256 loserStakeMultiplier; 61 | uint256 sharedStakeMultiplier; 62 | uint256 MULTIPLIER_DIVISOR; 63 | uint256 arbitrationCost; 64 | } 65 | 66 | /** @dev Fetch arbitrable TCR data in a single call. 67 | * @param _address The address of the LightGeneralized TCR to query. 68 | * @return The latest data on an arbitrable TCR contract. 69 | */ 70 | function fetchArbitrable(address _address) external view returns (ArbitrableData memory result) { 71 | LightGeneralizedTCR tcr = LightGeneralizedTCR(_address); 72 | result.governor = tcr.governor(); 73 | result.arbitrator = address(tcr.arbitrator()); 74 | result.arbitratorExtraData = tcr.arbitratorExtraData(); 75 | result.submissionBaseDeposit = tcr.submissionBaseDeposit(); 76 | result.removalBaseDeposit = tcr.removalBaseDeposit(); 77 | result.submissionChallengeBaseDeposit = tcr.submissionChallengeBaseDeposit(); 78 | result.removalChallengeBaseDeposit = tcr.removalChallengeBaseDeposit(); 79 | result.challengePeriodDuration = tcr.challengePeriodDuration(); 80 | result.metaEvidenceUpdates = tcr.metaEvidenceUpdates(); 81 | result.winnerStakeMultiplier = tcr.winnerStakeMultiplier(); 82 | result.loserStakeMultiplier = tcr.loserStakeMultiplier(); 83 | result.sharedStakeMultiplier = tcr.sharedStakeMultiplier(); 84 | result.MULTIPLIER_DIVISOR = tcr.MULTIPLIER_DIVISOR(); 85 | result.arbitrationCost = IArbitrator(result.arbitrator).arbitrationCost(result.arbitratorExtraData); 86 | } 87 | 88 | /** @dev Fetch the latest data on an item in a single call. 89 | * @param _address The address of the LightGeneralized TCR to query. 90 | * @param _itemID The ID of the item to query. 91 | * @return The item data. 92 | */ 93 | function getItem(address _address, bytes32 _itemID) public view returns (QueryResult memory result) { 94 | RoundData memory round = getLatestRoundRequestData(_address, _itemID); 95 | result = QueryResult({ 96 | ID: _itemID, 97 | status: round.request.item.status, 98 | disputed: round.request.disputed, 99 | resolved: round.request.resolved, 100 | disputeID: round.request.disputeID, 101 | appealCost: 0, 102 | appealed: round.appealed, 103 | appealStart: 0, 104 | appealEnd: 0, 105 | ruling: round.request.ruling, 106 | requester: round.request.parties[uint256(LightGeneralizedTCR.Party.Requester)], 107 | challenger: round.request.parties[uint256(LightGeneralizedTCR.Party.Challenger)], 108 | arbitrator: address(round.request.arbitrator), 109 | arbitratorExtraData: round.request.arbitratorExtraData, 110 | currentRuling: LightGeneralizedTCR.Party.None, 111 | hasPaid: round.hasPaid, 112 | feeRewards: round.feeRewards, 113 | submissionTime: round.request.submissionTime, 114 | amountPaid: round.amountPaid, 115 | disputeStatus: IArbitrator.DisputeStatus.Waiting, 116 | numberOfRequests: round.request.item.numberOfRequests 117 | }); 118 | if ( 119 | round.request.disputed && 120 | round.request.arbitrator.disputeStatus(result.disputeID) == IArbitrator.DisputeStatus.Appealable 121 | ) { 122 | result.currentRuling = LightGeneralizedTCR.Party(round.request.arbitrator.currentRuling(result.disputeID)); 123 | result.disputeStatus = round.request.arbitrator.disputeStatus(result.disputeID); 124 | (result.appealStart, result.appealEnd) = round.request.arbitrator.appealPeriod(result.disputeID); 125 | result.appealCost = round.request.arbitrator.appealCost(result.disputeID, result.arbitratorExtraData); 126 | } 127 | } 128 | 129 | struct ItemRequest { 130 | bool disputed; 131 | uint256 disputeID; 132 | uint256 submissionTime; 133 | bool resolved; 134 | address requester; 135 | address challenger; 136 | address arbitrator; 137 | bytes arbitratorExtraData; 138 | uint256 metaEvidenceID; 139 | } 140 | 141 | /** @dev Fetch all requests for an item. 142 | * @param _address The address of the LightGeneralized TCR to query. 143 | * @param _itemID The ID of the item to query. 144 | * @return The items requests. 145 | */ 146 | function getItemRequests(address _address, bytes32 _itemID) external view returns (ItemRequest[] memory requests) { 147 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 148 | ItemData memory itemData = getItemData(_address, _itemID); 149 | requests = new ItemRequest[](itemData.numberOfRequests); 150 | for (uint256 i = 0; i < itemData.numberOfRequests; i++) { 151 | ( 152 | bool disputed, 153 | uint256 disputeID, 154 | uint256 submissionTime, 155 | bool resolved, 156 | address payable[3] memory parties, 157 | , 158 | , 159 | IArbitrator arbitrator, 160 | bytes memory arbitratorExtraData, 161 | uint256 metaEvidenceID 162 | ) = gtcr.getRequestInfo(_itemID, i); 163 | 164 | // Sort requests by newest first. 165 | requests[itemData.numberOfRequests - i - 1] = ItemRequest({ 166 | disputed: disputed, 167 | disputeID: disputeID, 168 | submissionTime: submissionTime, 169 | resolved: resolved, 170 | requester: parties[uint256(LightGeneralizedTCR.Party.Requester)], 171 | challenger: parties[uint256(LightGeneralizedTCR.Party.Challenger)], 172 | arbitrator: address(arbitrator), 173 | arbitratorExtraData: arbitratorExtraData, 174 | metaEvidenceID: metaEvidenceID 175 | }); 176 | } 177 | } 178 | 179 | /** @dev Return the withdrawable rewards for a contributor. 180 | * @param _address The address of the LightGeneralized TCR to query. 181 | * @param _itemID The ID of the item to query. 182 | * @param _contributor The address of the contributor. 183 | * @return The amount withdrawable per round per request. 184 | */ 185 | function availableRewards( 186 | address _address, 187 | bytes32 _itemID, 188 | address _contributor 189 | ) external view returns (uint256 rewards) { 190 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 191 | 192 | // Using arrays to avoid stack limit. 193 | uint256[2] memory requestRoundCount = [uint256(0), uint256(0)]; 194 | uint256[2] memory indexes = [uint256(0), uint256(0)]; // Request index and round index. 195 | 196 | (, requestRoundCount[0], ) = gtcr.getItemInfo(_itemID); 197 | for (indexes[0]; indexes[0] < requestRoundCount[0]; indexes[0]++) { 198 | LightGeneralizedTCR.Party ruling; 199 | bool resolved; 200 | (, , , resolved, , requestRoundCount[1], ruling, , , ) = gtcr.getRequestInfo(_itemID, indexes[0]); 201 | if (!resolved) continue; 202 | for (indexes[1]; indexes[1] < requestRoundCount[1]; indexes[1]++) { 203 | (, uint256[3] memory amountPaid, bool[3] memory hasPaid, uint256 feeRewards) = gtcr.getRoundInfo( 204 | _itemID, 205 | indexes[0], 206 | indexes[1] 207 | ); 208 | 209 | uint256[3] memory roundContributions = gtcr.getContributions( 210 | _itemID, 211 | indexes[0], 212 | indexes[1], 213 | _contributor 214 | ); 215 | if ( 216 | !hasPaid[uint256(LightGeneralizedTCR.Party.Requester)] || 217 | !hasPaid[uint256(LightGeneralizedTCR.Party.Challenger)] 218 | ) { 219 | // Amount reimbursable if not enough fees were raised to appeal the ruling. 220 | rewards += 221 | roundContributions[uint256(LightGeneralizedTCR.Party.Requester)] + 222 | roundContributions[uint256(LightGeneralizedTCR.Party.Challenger)]; 223 | } else if (ruling == LightGeneralizedTCR.Party.None) { 224 | // Reimbursable fees proportional if there aren't a winner and loser. 225 | rewards += amountPaid[uint256(LightGeneralizedTCR.Party.Requester)] > 0 226 | ? (roundContributions[uint256(LightGeneralizedTCR.Party.Requester)] * feeRewards) / 227 | (amountPaid[uint256(LightGeneralizedTCR.Party.Challenger)] + 228 | amountPaid[uint256(LightGeneralizedTCR.Party.Requester)]) 229 | : 0; 230 | rewards += amountPaid[uint256(LightGeneralizedTCR.Party.Challenger)] > 0 231 | ? (roundContributions[uint256(LightGeneralizedTCR.Party.Challenger)] * feeRewards) / 232 | (amountPaid[uint256(LightGeneralizedTCR.Party.Challenger)] + 233 | amountPaid[uint256(LightGeneralizedTCR.Party.Requester)]) 234 | : 0; 235 | } else { 236 | // Contributors to the winner take the rewards. 237 | rewards += amountPaid[uint256(ruling)] > 0 238 | ? (roundContributions[uint256(ruling)] * feeRewards) / amountPaid[uint256(ruling)] 239 | : 0; 240 | } 241 | } 242 | indexes[1] = 0; 243 | } 244 | } 245 | 246 | // Functions and structs below used mainly to avoid stack limit. 247 | struct ItemData { 248 | LightGeneralizedTCR.Status status; 249 | uint256 numberOfRequests; 250 | } 251 | 252 | struct RequestData { 253 | ItemData item; 254 | bool disputed; 255 | uint256 disputeID; 256 | uint256 submissionTime; 257 | bool resolved; 258 | address payable[3] parties; 259 | uint256 numberOfRounds; 260 | LightGeneralizedTCR.Party ruling; 261 | IArbitrator arbitrator; 262 | bytes arbitratorExtraData; 263 | } 264 | 265 | struct RoundData { 266 | RequestData request; 267 | bool appealed; 268 | uint256[3] amountPaid; 269 | bool[3] hasPaid; 270 | uint256 feeRewards; 271 | } 272 | 273 | /** @dev Fetch data of the an item and return a struct. 274 | * @param _address The address of the LightGeneralized TCR to query. 275 | * @param _itemID The ID of the item to query. 276 | * @return The round data. 277 | */ 278 | function getItemData(address _address, bytes32 _itemID) public view returns (ItemData memory item) { 279 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 280 | (LightGeneralizedTCR.Status status, uint256 numberOfRequests, ) = gtcr.getItemInfo(_itemID); 281 | item = ItemData(status, numberOfRequests); 282 | } 283 | 284 | /** @dev Fetch the latest request of item. 285 | * @param _address The address of the LightGeneralized TCR to query. 286 | * @param _itemID The ID of the item to query. 287 | * @return The round data. 288 | */ 289 | function getLatestRequestData(address _address, bytes32 _itemID) public view returns (RequestData memory request) { 290 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 291 | ItemData memory item = getItemData(_address, _itemID); 292 | ( 293 | bool disputed, 294 | uint256 disputeID, 295 | uint256 submissionTime, 296 | bool resolved, 297 | address payable[3] memory parties, 298 | uint256 numberOfRounds, 299 | LightGeneralizedTCR.Party ruling, 300 | IArbitrator arbitrator, 301 | bytes memory arbitratorExtraData, 302 | 303 | ) = gtcr.getRequestInfo(_itemID, item.numberOfRequests - 1); 304 | request = RequestData( 305 | item, 306 | disputed, 307 | disputeID, 308 | submissionTime, 309 | resolved, 310 | parties, 311 | numberOfRounds, 312 | ruling, 313 | arbitrator, 314 | arbitratorExtraData 315 | ); 316 | } 317 | 318 | /** @dev Fetch the latest round of the latest request of an item. 319 | * @param _address The address of the LightGeneralized TCR to query. 320 | * @param _itemID The ID of the item to query. 321 | * @return The round data. 322 | */ 323 | function getLatestRoundRequestData(address _address, bytes32 _itemID) public view returns (RoundData memory round) { 324 | LightGeneralizedTCR gtcr = LightGeneralizedTCR(_address); 325 | (, , uint256 sumDeposit) = gtcr.getItemInfo(_itemID); 326 | RequestData memory request = getLatestRequestData(_address, _itemID); 327 | 328 | if (request.disputed) { 329 | (bool appealed, uint256[3] memory amountPaid, bool[3] memory hasPaid, uint256 feeRewards) = gtcr 330 | .getRoundInfo(_itemID, request.item.numberOfRequests - 1, request.numberOfRounds - 1); 331 | 332 | round = RoundData(request, appealed, amountPaid, hasPaid, feeRewards); 333 | } else { 334 | round = RoundData(request, false, [0, sumDeposit, 0], [false, true, false], sumDeposit); 335 | } 336 | } 337 | } 338 | -------------------------------------------------------------------------------- /deploy/deploy.js: -------------------------------------------------------------------------------- 1 | module.exports = async ({ getNamedAccounts, deployments }) => { 2 | const { deploy } = deployments; 3 | const { deployer, governor } = await getNamedAccounts(); 4 | const arbitratorExtraData = "0x85"; 5 | const arbitrationCost = 1000; 6 | const appealTimeOut = 180; 7 | 8 | // the following will deploy "EnhancedAppealableArbitrator" if the contract was never deployed or if the code changed since last deployment 9 | const EnhancedArbitrator = await deploy("EnhancedAppealableArbitrator", { 10 | from: governor, 11 | args: [arbitrationCost, governor, arbitratorExtraData, appealTimeOut], 12 | }); 13 | console.log(EnhancedArbitrator.address, "EnhancedAppealableArbitrator"); 14 | const GTCRFactory = await deploy("GTCRFactory", { 15 | from: deployer, 16 | args: [], 17 | }); 18 | 19 | console.log(GTCRFactory.address, "GTCRFactory address"); 20 | const LGTCR = await deploy("LightGeneralizedTCR", { 21 | from: deployer, 22 | args: [], 23 | }); 24 | console.log(LGTCR.address, "address of LGTCR"); 25 | const LGTCRFactory = await deploy("LightGTCRFactory", { 26 | from: deployer, 27 | args: [LGTCR.address], 28 | }); 29 | const RelayMock = await deploy("RelayMock", { 30 | from: governor, 31 | args: [], 32 | }); 33 | console.log(RelayMock.address, "address of RelayMock"); 34 | console.log(LGTCRFactory.address, "address of LGTCR factory"); 35 | const LightGeneralizedTCRView = await deploy("LightGeneralizedTCRView", { 36 | from: governor, 37 | args: [], 38 | }); 39 | console.log(LightGeneralizedTCRView.address, "address of LightGeneralizedTCRView"); 40 | 41 | const GeneralizedTCRView = await deploy("GeneralizedTCRView", { 42 | from: governor, 43 | args: [], 44 | }); 45 | console.log(GeneralizedTCRView.address, "address of GeneralizedTCRView"); 46 | 47 | const BatchWithdraw = await deploy("BatchWithdraw", { 48 | from: governor, 49 | args: [], 50 | }); 51 | console.log(BatchWithdraw.address, "address of BatchWithdraw"); 52 | const LBatchWithdraw = await deploy("LightBatchWithdraw", { 53 | from: governor, 54 | args: [], 55 | }); 56 | console.log(LBatchWithdraw.address, "address of LightBatchWithdraw"); 57 | }; 58 | module.exports.tags = ["gtcrContracts"]; 59 | -------------------------------------------------------------------------------- /deployments/goerli/.chainId: -------------------------------------------------------------------------------- 1 | 5 -------------------------------------------------------------------------------- /deployments/mainnet/.chainId: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /deployments/mainnet/BatchWithdraw.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x38aA214Dc986d0bAB53E5861071f3d5a56066b4D", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "internalType": "address", 9 | "name": "_address", 10 | "type": "address" 11 | }, 12 | { 13 | "internalType": "address payable", 14 | "name": "_contributor", 15 | "type": "address" 16 | }, 17 | { 18 | "internalType": "bytes32", 19 | "name": "_itemID", 20 | "type": "bytes32" 21 | }, 22 | { 23 | "internalType": "uint256", 24 | "name": "_cursor", 25 | "type": "uint256" 26 | }, 27 | { 28 | "internalType": "uint256", 29 | "name": "_count", 30 | "type": "uint256" 31 | }, 32 | { 33 | "internalType": "uint256", 34 | "name": "_roundCursor", 35 | "type": "uint256" 36 | }, 37 | { 38 | "internalType": "uint256", 39 | "name": "_roundCount", 40 | "type": "uint256" 41 | } 42 | ], 43 | "name": "batchRequestWithdraw", 44 | "outputs": [], 45 | "payable": false, 46 | "stateMutability": "nonpayable", 47 | "type": "function" 48 | }, 49 | { 50 | "constant": false, 51 | "inputs": [ 52 | { 53 | "internalType": "address", 54 | "name": "_address", 55 | "type": "address" 56 | }, 57 | { 58 | "internalType": "address payable", 59 | "name": "_contributor", 60 | "type": "address" 61 | }, 62 | { 63 | "internalType": "bytes32", 64 | "name": "_itemID", 65 | "type": "bytes32" 66 | }, 67 | { 68 | "internalType": "uint256", 69 | "name": "_request", 70 | "type": "uint256" 71 | }, 72 | { 73 | "internalType": "uint256", 74 | "name": "_cursor", 75 | "type": "uint256" 76 | }, 77 | { 78 | "internalType": "uint256", 79 | "name": "_count", 80 | "type": "uint256" 81 | } 82 | ], 83 | "name": "batchRoundWithdraw", 84 | "outputs": [], 85 | "payable": false, 86 | "stateMutability": "nonpayable", 87 | "type": "function" 88 | } 89 | ] 90 | } 91 | -------------------------------------------------------------------------------- /deployments/mainnet/GeneralizedTCR.json: -------------------------------------------------------------------------------- 1 | { 2 | "address":"0xbA0304273a54dfeC1Fc7f4BCCbf4b15519AEcF15", 3 | "abi": [ 4 | { 5 | "inputs": [ 6 | { 7 | "internalType": "contract IArbitrator", 8 | "name": "_arbitrator", 9 | "type": "address" 10 | }, 11 | { 12 | "internalType": "bytes", 13 | "name": "_arbitratorExtraData", 14 | "type": "bytes" 15 | }, 16 | { 17 | "internalType": "address", 18 | "name": "_connectedTCR", 19 | "type": "address" 20 | }, 21 | { 22 | "internalType": "string", 23 | "name": "_registrationMetaEvidence", 24 | "type": "string" 25 | }, 26 | { 27 | "internalType": "string", 28 | "name": "_clearingMetaEvidence", 29 | "type": "string" 30 | }, 31 | { 32 | "internalType": "address", 33 | "name": "_governor", 34 | "type": "address" 35 | }, 36 | { 37 | "internalType": "uint256", 38 | "name": "_submissionBaseDeposit", 39 | "type": "uint256" 40 | }, 41 | { 42 | "internalType": "uint256", 43 | "name": "_removalBaseDeposit", 44 | "type": "uint256" 45 | }, 46 | { 47 | "internalType": "uint256", 48 | "name": "_submissionChallengeBaseDeposit", 49 | "type": "uint256" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "_removalChallengeBaseDeposit", 54 | "type": "uint256" 55 | }, 56 | { 57 | "internalType": "uint256", 58 | "name": "_challengePeriodDuration", 59 | "type": "uint256" 60 | }, 61 | { 62 | "internalType": "uint256[3]", 63 | "name": "_stakeMultipliers", 64 | "type": "uint256[3]" 65 | } 66 | ], 67 | "payable": false, 68 | "stateMutability": "nonpayable", 69 | "type": "constructor" 70 | }, 71 | { 72 | "anonymous": false, 73 | "inputs": [ 74 | { 75 | "indexed": true, 76 | "internalType": "bytes32", 77 | "name": "_itemID", 78 | "type": "bytes32" 79 | }, 80 | { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "_contributor", 84 | "type": "address" 85 | }, 86 | { 87 | "indexed": true, 88 | "internalType": "uint256", 89 | "name": "_request", 90 | "type": "uint256" 91 | }, 92 | { 93 | "indexed": false, 94 | "internalType": "uint256", 95 | "name": "_round", 96 | "type": "uint256" 97 | }, 98 | { 99 | "indexed": false, 100 | "internalType": "uint256", 101 | "name": "_amount", 102 | "type": "uint256" 103 | }, 104 | { 105 | "indexed": false, 106 | "internalType": "enum GeneralizedTCR.Party", 107 | "name": "_side", 108 | "type": "uint8" 109 | } 110 | ], 111 | "name": "AppealContribution", 112 | "type": "event" 113 | }, 114 | { 115 | "anonymous": false, 116 | "inputs": [ 117 | { 118 | "indexed": true, 119 | "internalType": "address", 120 | "name": "_connectedTCR", 121 | "type": "address" 122 | } 123 | ], 124 | "name": "ConnectedTCRSet", 125 | "type": "event" 126 | }, 127 | { 128 | "anonymous": false, 129 | "inputs": [ 130 | { 131 | "indexed": true, 132 | "internalType": "contract IArbitrator", 133 | "name": "_arbitrator", 134 | "type": "address" 135 | }, 136 | { 137 | "indexed": true, 138 | "internalType": "uint256", 139 | "name": "_disputeID", 140 | "type": "uint256" 141 | }, 142 | { 143 | "indexed": false, 144 | "internalType": "uint256", 145 | "name": "_metaEvidenceID", 146 | "type": "uint256" 147 | }, 148 | { 149 | "indexed": false, 150 | "internalType": "uint256", 151 | "name": "_evidenceGroupID", 152 | "type": "uint256" 153 | } 154 | ], 155 | "name": "Dispute", 156 | "type": "event" 157 | }, 158 | { 159 | "anonymous": false, 160 | "inputs": [ 161 | { 162 | "indexed": true, 163 | "internalType": "contract IArbitrator", 164 | "name": "_arbitrator", 165 | "type": "address" 166 | }, 167 | { 168 | "indexed": true, 169 | "internalType": "uint256", 170 | "name": "_evidenceGroupID", 171 | "type": "uint256" 172 | }, 173 | { 174 | "indexed": true, 175 | "internalType": "address", 176 | "name": "_party", 177 | "type": "address" 178 | }, 179 | { 180 | "indexed": false, 181 | "internalType": "string", 182 | "name": "_evidence", 183 | "type": "string" 184 | } 185 | ], 186 | "name": "Evidence", 187 | "type": "event" 188 | }, 189 | { 190 | "anonymous": false, 191 | "inputs": [ 192 | { 193 | "indexed": true, 194 | "internalType": "bytes32", 195 | "name": "_itemID", 196 | "type": "bytes32" 197 | }, 198 | { 199 | "indexed": true, 200 | "internalType": "uint256", 201 | "name": "_request", 202 | "type": "uint256" 203 | }, 204 | { 205 | "indexed": true, 206 | "internalType": "uint256", 207 | "name": "_round", 208 | "type": "uint256" 209 | }, 210 | { 211 | "indexed": false, 212 | "internalType": "enum GeneralizedTCR.Party", 213 | "name": "_side", 214 | "type": "uint8" 215 | } 216 | ], 217 | "name": "HasPaidAppealFee", 218 | "type": "event" 219 | }, 220 | { 221 | "anonymous": false, 222 | "inputs": [ 223 | { 224 | "indexed": true, 225 | "internalType": "bytes32", 226 | "name": "_itemID", 227 | "type": "bytes32" 228 | }, 229 | { 230 | "indexed": true, 231 | "internalType": "uint256", 232 | "name": "_requestIndex", 233 | "type": "uint256" 234 | }, 235 | { 236 | "indexed": true, 237 | "internalType": "uint256", 238 | "name": "_roundIndex", 239 | "type": "uint256" 240 | }, 241 | { 242 | "indexed": false, 243 | "internalType": "bool", 244 | "name": "_disputed", 245 | "type": "bool" 246 | }, 247 | { 248 | "indexed": false, 249 | "internalType": "bool", 250 | "name": "_resolved", 251 | "type": "bool" 252 | } 253 | ], 254 | "name": "ItemStatusChange", 255 | "type": "event" 256 | }, 257 | { 258 | "anonymous": false, 259 | "inputs": [ 260 | { 261 | "indexed": true, 262 | "internalType": "bytes32", 263 | "name": "_itemID", 264 | "type": "bytes32" 265 | }, 266 | { 267 | "indexed": true, 268 | "internalType": "address", 269 | "name": "_submitter", 270 | "type": "address" 271 | }, 272 | { 273 | "indexed": true, 274 | "internalType": "uint256", 275 | "name": "_evidenceGroupID", 276 | "type": "uint256" 277 | }, 278 | { 279 | "indexed": false, 280 | "internalType": "bytes", 281 | "name": "_data", 282 | "type": "bytes" 283 | } 284 | ], 285 | "name": "ItemSubmitted", 286 | "type": "event" 287 | }, 288 | { 289 | "anonymous": false, 290 | "inputs": [ 291 | { 292 | "indexed": true, 293 | "internalType": "uint256", 294 | "name": "_metaEvidenceID", 295 | "type": "uint256" 296 | }, 297 | { 298 | "indexed": false, 299 | "internalType": "string", 300 | "name": "_evidence", 301 | "type": "string" 302 | } 303 | ], 304 | "name": "MetaEvidence", 305 | "type": "event" 306 | }, 307 | { 308 | "anonymous": false, 309 | "inputs": [ 310 | { 311 | "indexed": true, 312 | "internalType": "bytes32", 313 | "name": "_itemID", 314 | "type": "bytes32" 315 | }, 316 | { 317 | "indexed": true, 318 | "internalType": "uint256", 319 | "name": "_requestIndex", 320 | "type": "uint256" 321 | }, 322 | { 323 | "indexed": true, 324 | "internalType": "uint256", 325 | "name": "_evidenceGroupID", 326 | "type": "uint256" 327 | } 328 | ], 329 | "name": "RequestEvidenceGroupID", 330 | "type": "event" 331 | }, 332 | { 333 | "anonymous": false, 334 | "inputs": [ 335 | { 336 | "indexed": true, 337 | "internalType": "bytes32", 338 | "name": "_itemID", 339 | "type": "bytes32" 340 | }, 341 | { 342 | "indexed": true, 343 | "internalType": "uint256", 344 | "name": "_requestIndex", 345 | "type": "uint256" 346 | }, 347 | { 348 | "indexed": true, 349 | "internalType": "enum GeneralizedTCR.Status", 350 | "name": "_requestType", 351 | "type": "uint8" 352 | } 353 | ], 354 | "name": "RequestSubmitted", 355 | "type": "event" 356 | }, 357 | { 358 | "anonymous": false, 359 | "inputs": [ 360 | { 361 | "indexed": true, 362 | "internalType": "contract IArbitrator", 363 | "name": "_arbitrator", 364 | "type": "address" 365 | }, 366 | { 367 | "indexed": true, 368 | "internalType": "uint256", 369 | "name": "_disputeID", 370 | "type": "uint256" 371 | }, 372 | { 373 | "indexed": false, 374 | "internalType": "uint256", 375 | "name": "_ruling", 376 | "type": "uint256" 377 | } 378 | ], 379 | "name": "Ruling", 380 | "type": "event" 381 | }, 382 | { 383 | "constant": true, 384 | "inputs": [], 385 | "name": "MULTIPLIER_DIVISOR", 386 | "outputs": [ 387 | { 388 | "internalType": "uint256", 389 | "name": "", 390 | "type": "uint256" 391 | } 392 | ], 393 | "payable": false, 394 | "stateMutability": "view", 395 | "type": "function" 396 | }, 397 | { 398 | "constant": false, 399 | "inputs": [ 400 | { 401 | "internalType": "bytes", 402 | "name": "_item", 403 | "type": "bytes" 404 | } 405 | ], 406 | "name": "addItem", 407 | "outputs": [], 408 | "payable": true, 409 | "stateMutability": "payable", 410 | "type": "function" 411 | }, 412 | { 413 | "constant": true, 414 | "inputs": [], 415 | "name": "arbitrator", 416 | "outputs": [ 417 | { 418 | "internalType": "contract IArbitrator", 419 | "name": "", 420 | "type": "address" 421 | } 422 | ], 423 | "payable": false, 424 | "stateMutability": "view", 425 | "type": "function" 426 | }, 427 | { 428 | "constant": true, 429 | "inputs": [ 430 | { 431 | "internalType": "address", 432 | "name": "", 433 | "type": "address" 434 | }, 435 | { 436 | "internalType": "uint256", 437 | "name": "", 438 | "type": "uint256" 439 | } 440 | ], 441 | "name": "arbitratorDisputeIDToItem", 442 | "outputs": [ 443 | { 444 | "internalType": "bytes32", 445 | "name": "", 446 | "type": "bytes32" 447 | } 448 | ], 449 | "payable": false, 450 | "stateMutability": "view", 451 | "type": "function" 452 | }, 453 | { 454 | "constant": true, 455 | "inputs": [], 456 | "name": "arbitratorExtraData", 457 | "outputs": [ 458 | { 459 | "internalType": "bytes", 460 | "name": "", 461 | "type": "bytes" 462 | } 463 | ], 464 | "payable": false, 465 | "stateMutability": "view", 466 | "type": "function" 467 | }, 468 | { 469 | "constant": true, 470 | "inputs": [], 471 | "name": "challengePeriodDuration", 472 | "outputs": [ 473 | { 474 | "internalType": "uint256", 475 | "name": "", 476 | "type": "uint256" 477 | } 478 | ], 479 | "payable": false, 480 | "stateMutability": "view", 481 | "type": "function" 482 | }, 483 | { 484 | "constant": false, 485 | "inputs": [ 486 | { 487 | "internalType": "bytes32", 488 | "name": "_itemID", 489 | "type": "bytes32" 490 | }, 491 | { 492 | "internalType": "string", 493 | "name": "_evidence", 494 | "type": "string" 495 | } 496 | ], 497 | "name": "challengeRequest", 498 | "outputs": [], 499 | "payable": true, 500 | "stateMutability": "payable", 501 | "type": "function" 502 | }, 503 | { 504 | "constant": false, 505 | "inputs": [ 506 | { 507 | "internalType": "contract IArbitrator", 508 | "name": "_arbitrator", 509 | "type": "address" 510 | }, 511 | { 512 | "internalType": "bytes", 513 | "name": "_arbitratorExtraData", 514 | "type": "bytes" 515 | } 516 | ], 517 | "name": "changeArbitrator", 518 | "outputs": [], 519 | "payable": false, 520 | "stateMutability": "nonpayable", 521 | "type": "function" 522 | }, 523 | { 524 | "constant": false, 525 | "inputs": [ 526 | { 527 | "internalType": "address", 528 | "name": "_connectedTCR", 529 | "type": "address" 530 | } 531 | ], 532 | "name": "changeConnectedTCR", 533 | "outputs": [], 534 | "payable": false, 535 | "stateMutability": "nonpayable", 536 | "type": "function" 537 | }, 538 | { 539 | "constant": false, 540 | "inputs": [ 541 | { 542 | "internalType": "address", 543 | "name": "_governor", 544 | "type": "address" 545 | } 546 | ], 547 | "name": "changeGovernor", 548 | "outputs": [], 549 | "payable": false, 550 | "stateMutability": "nonpayable", 551 | "type": "function" 552 | }, 553 | { 554 | "constant": false, 555 | "inputs": [ 556 | { 557 | "internalType": "uint256", 558 | "name": "_loserStakeMultiplier", 559 | "type": "uint256" 560 | } 561 | ], 562 | "name": "changeLoserStakeMultiplier", 563 | "outputs": [], 564 | "payable": false, 565 | "stateMutability": "nonpayable", 566 | "type": "function" 567 | }, 568 | { 569 | "constant": false, 570 | "inputs": [ 571 | { 572 | "internalType": "string", 573 | "name": "_registrationMetaEvidence", 574 | "type": "string" 575 | }, 576 | { 577 | "internalType": "string", 578 | "name": "_clearingMetaEvidence", 579 | "type": "string" 580 | } 581 | ], 582 | "name": "changeMetaEvidence", 583 | "outputs": [], 584 | "payable": false, 585 | "stateMutability": "nonpayable", 586 | "type": "function" 587 | }, 588 | { 589 | "constant": false, 590 | "inputs": [ 591 | { 592 | "internalType": "uint256", 593 | "name": "_removalBaseDeposit", 594 | "type": "uint256" 595 | } 596 | ], 597 | "name": "changeRemovalBaseDeposit", 598 | "outputs": [], 599 | "payable": false, 600 | "stateMutability": "nonpayable", 601 | "type": "function" 602 | }, 603 | { 604 | "constant": false, 605 | "inputs": [ 606 | { 607 | "internalType": "uint256", 608 | "name": "_removalChallengeBaseDeposit", 609 | "type": "uint256" 610 | } 611 | ], 612 | "name": "changeRemovalChallengeBaseDeposit", 613 | "outputs": [], 614 | "payable": false, 615 | "stateMutability": "nonpayable", 616 | "type": "function" 617 | }, 618 | { 619 | "constant": false, 620 | "inputs": [ 621 | { 622 | "internalType": "uint256", 623 | "name": "_sharedStakeMultiplier", 624 | "type": "uint256" 625 | } 626 | ], 627 | "name": "changeSharedStakeMultiplier", 628 | "outputs": [], 629 | "payable": false, 630 | "stateMutability": "nonpayable", 631 | "type": "function" 632 | }, 633 | { 634 | "constant": false, 635 | "inputs": [ 636 | { 637 | "internalType": "uint256", 638 | "name": "_submissionBaseDeposit", 639 | "type": "uint256" 640 | } 641 | ], 642 | "name": "changeSubmissionBaseDeposit", 643 | "outputs": [], 644 | "payable": false, 645 | "stateMutability": "nonpayable", 646 | "type": "function" 647 | }, 648 | { 649 | "constant": false, 650 | "inputs": [ 651 | { 652 | "internalType": "uint256", 653 | "name": "_submissionChallengeBaseDeposit", 654 | "type": "uint256" 655 | } 656 | ], 657 | "name": "changeSubmissionChallengeBaseDeposit", 658 | "outputs": [], 659 | "payable": false, 660 | "stateMutability": "nonpayable", 661 | "type": "function" 662 | }, 663 | { 664 | "constant": false, 665 | "inputs": [ 666 | { 667 | "internalType": "uint256", 668 | "name": "_challengePeriodDuration", 669 | "type": "uint256" 670 | } 671 | ], 672 | "name": "changeTimeToChallenge", 673 | "outputs": [], 674 | "payable": false, 675 | "stateMutability": "nonpayable", 676 | "type": "function" 677 | }, 678 | { 679 | "constant": false, 680 | "inputs": [ 681 | { 682 | "internalType": "uint256", 683 | "name": "_winnerStakeMultiplier", 684 | "type": "uint256" 685 | } 686 | ], 687 | "name": "changeWinnerStakeMultiplier", 688 | "outputs": [], 689 | "payable": false, 690 | "stateMutability": "nonpayable", 691 | "type": "function" 692 | }, 693 | { 694 | "constant": false, 695 | "inputs": [ 696 | { 697 | "internalType": "bytes32", 698 | "name": "_itemID", 699 | "type": "bytes32" 700 | } 701 | ], 702 | "name": "executeRequest", 703 | "outputs": [], 704 | "payable": false, 705 | "stateMutability": "nonpayable", 706 | "type": "function" 707 | }, 708 | { 709 | "constant": false, 710 | "inputs": [ 711 | { 712 | "internalType": "bytes32", 713 | "name": "_itemID", 714 | "type": "bytes32" 715 | }, 716 | { 717 | "internalType": "enum GeneralizedTCR.Party", 718 | "name": "_side", 719 | "type": "uint8" 720 | } 721 | ], 722 | "name": "fundAppeal", 723 | "outputs": [], 724 | "payable": true, 725 | "stateMutability": "payable", 726 | "type": "function" 727 | }, 728 | { 729 | "constant": true, 730 | "inputs": [ 731 | { 732 | "internalType": "bytes32", 733 | "name": "_itemID", 734 | "type": "bytes32" 735 | }, 736 | { 737 | "internalType": "uint256", 738 | "name": "_request", 739 | "type": "uint256" 740 | }, 741 | { 742 | "internalType": "uint256", 743 | "name": "_round", 744 | "type": "uint256" 745 | }, 746 | { 747 | "internalType": "address", 748 | "name": "_contributor", 749 | "type": "address" 750 | } 751 | ], 752 | "name": "getContributions", 753 | "outputs": [ 754 | { 755 | "internalType": "uint256[3]", 756 | "name": "contributions", 757 | "type": "uint256[3]" 758 | } 759 | ], 760 | "payable": false, 761 | "stateMutability": "view", 762 | "type": "function" 763 | }, 764 | { 765 | "constant": true, 766 | "inputs": [ 767 | { 768 | "internalType": "bytes32", 769 | "name": "_itemID", 770 | "type": "bytes32" 771 | } 772 | ], 773 | "name": "getItemInfo", 774 | "outputs": [ 775 | { 776 | "internalType": "bytes", 777 | "name": "data", 778 | "type": "bytes" 779 | }, 780 | { 781 | "internalType": "enum GeneralizedTCR.Status", 782 | "name": "status", 783 | "type": "uint8" 784 | }, 785 | { 786 | "internalType": "uint256", 787 | "name": "numberOfRequests", 788 | "type": "uint256" 789 | } 790 | ], 791 | "payable": false, 792 | "stateMutability": "view", 793 | "type": "function" 794 | }, 795 | { 796 | "constant": true, 797 | "inputs": [ 798 | { 799 | "internalType": "bytes32", 800 | "name": "_itemID", 801 | "type": "bytes32" 802 | }, 803 | { 804 | "internalType": "uint256", 805 | "name": "_request", 806 | "type": "uint256" 807 | } 808 | ], 809 | "name": "getRequestInfo", 810 | "outputs": [ 811 | { 812 | "internalType": "bool", 813 | "name": "disputed", 814 | "type": "bool" 815 | }, 816 | { 817 | "internalType": "uint256", 818 | "name": "disputeID", 819 | "type": "uint256" 820 | }, 821 | { 822 | "internalType": "uint256", 823 | "name": "submissionTime", 824 | "type": "uint256" 825 | }, 826 | { 827 | "internalType": "bool", 828 | "name": "resolved", 829 | "type": "bool" 830 | }, 831 | { 832 | "internalType": "address payable[3]", 833 | "name": "parties", 834 | "type": "address[3]" 835 | }, 836 | { 837 | "internalType": "uint256", 838 | "name": "numberOfRounds", 839 | "type": "uint256" 840 | }, 841 | { 842 | "internalType": "enum GeneralizedTCR.Party", 843 | "name": "ruling", 844 | "type": "uint8" 845 | }, 846 | { 847 | "internalType": "contract IArbitrator", 848 | "name": "arbitrator", 849 | "type": "address" 850 | }, 851 | { 852 | "internalType": "bytes", 853 | "name": "arbitratorExtraData", 854 | "type": "bytes" 855 | }, 856 | { 857 | "internalType": "uint256", 858 | "name": "metaEvidenceID", 859 | "type": "uint256" 860 | } 861 | ], 862 | "payable": false, 863 | "stateMutability": "view", 864 | "type": "function" 865 | }, 866 | { 867 | "constant": true, 868 | "inputs": [ 869 | { 870 | "internalType": "bytes32", 871 | "name": "_itemID", 872 | "type": "bytes32" 873 | }, 874 | { 875 | "internalType": "uint256", 876 | "name": "_request", 877 | "type": "uint256" 878 | }, 879 | { 880 | "internalType": "uint256", 881 | "name": "_round", 882 | "type": "uint256" 883 | } 884 | ], 885 | "name": "getRoundInfo", 886 | "outputs": [ 887 | { 888 | "internalType": "bool", 889 | "name": "appealed", 890 | "type": "bool" 891 | }, 892 | { 893 | "internalType": "uint256[3]", 894 | "name": "amountPaid", 895 | "type": "uint256[3]" 896 | }, 897 | { 898 | "internalType": "bool[3]", 899 | "name": "hasPaid", 900 | "type": "bool[3]" 901 | }, 902 | { 903 | "internalType": "uint256", 904 | "name": "feeRewards", 905 | "type": "uint256" 906 | } 907 | ], 908 | "payable": false, 909 | "stateMutability": "view", 910 | "type": "function" 911 | }, 912 | { 913 | "constant": true, 914 | "inputs": [], 915 | "name": "governor", 916 | "outputs": [ 917 | { 918 | "internalType": "address", 919 | "name": "", 920 | "type": "address" 921 | } 922 | ], 923 | "payable": false, 924 | "stateMutability": "view", 925 | "type": "function" 926 | }, 927 | { 928 | "constant": true, 929 | "inputs": [], 930 | "name": "itemCount", 931 | "outputs": [ 932 | { 933 | "internalType": "uint256", 934 | "name": "count", 935 | "type": "uint256" 936 | } 937 | ], 938 | "payable": false, 939 | "stateMutability": "view", 940 | "type": "function" 941 | }, 942 | { 943 | "constant": true, 944 | "inputs": [ 945 | { 946 | "internalType": "bytes32", 947 | "name": "", 948 | "type": "bytes32" 949 | } 950 | ], 951 | "name": "itemIDtoIndex", 952 | "outputs": [ 953 | { 954 | "internalType": "uint256", 955 | "name": "", 956 | "type": "uint256" 957 | } 958 | ], 959 | "payable": false, 960 | "stateMutability": "view", 961 | "type": "function" 962 | }, 963 | { 964 | "constant": true, 965 | "inputs": [ 966 | { 967 | "internalType": "uint256", 968 | "name": "", 969 | "type": "uint256" 970 | } 971 | ], 972 | "name": "itemList", 973 | "outputs": [ 974 | { 975 | "internalType": "bytes32", 976 | "name": "", 977 | "type": "bytes32" 978 | } 979 | ], 980 | "payable": false, 981 | "stateMutability": "view", 982 | "type": "function" 983 | }, 984 | { 985 | "constant": true, 986 | "inputs": [ 987 | { 988 | "internalType": "bytes32", 989 | "name": "", 990 | "type": "bytes32" 991 | } 992 | ], 993 | "name": "items", 994 | "outputs": [ 995 | { 996 | "internalType": "bytes", 997 | "name": "data", 998 | "type": "bytes" 999 | }, 1000 | { 1001 | "internalType": "enum GeneralizedTCR.Status", 1002 | "name": "status", 1003 | "type": "uint8" 1004 | } 1005 | ], 1006 | "payable": false, 1007 | "stateMutability": "view", 1008 | "type": "function" 1009 | }, 1010 | { 1011 | "constant": true, 1012 | "inputs": [], 1013 | "name": "loserStakeMultiplier", 1014 | "outputs": [ 1015 | { 1016 | "internalType": "uint256", 1017 | "name": "", 1018 | "type": "uint256" 1019 | } 1020 | ], 1021 | "payable": false, 1022 | "stateMutability": "view", 1023 | "type": "function" 1024 | }, 1025 | { 1026 | "constant": true, 1027 | "inputs": [], 1028 | "name": "metaEvidenceUpdates", 1029 | "outputs": [ 1030 | { 1031 | "internalType": "uint256", 1032 | "name": "", 1033 | "type": "uint256" 1034 | } 1035 | ], 1036 | "payable": false, 1037 | "stateMutability": "view", 1038 | "type": "function" 1039 | }, 1040 | { 1041 | "constant": true, 1042 | "inputs": [], 1043 | "name": "removalBaseDeposit", 1044 | "outputs": [ 1045 | { 1046 | "internalType": "uint256", 1047 | "name": "", 1048 | "type": "uint256" 1049 | } 1050 | ], 1051 | "payable": false, 1052 | "stateMutability": "view", 1053 | "type": "function" 1054 | }, 1055 | { 1056 | "constant": true, 1057 | "inputs": [], 1058 | "name": "removalChallengeBaseDeposit", 1059 | "outputs": [ 1060 | { 1061 | "internalType": "uint256", 1062 | "name": "", 1063 | "type": "uint256" 1064 | } 1065 | ], 1066 | "payable": false, 1067 | "stateMutability": "view", 1068 | "type": "function" 1069 | }, 1070 | { 1071 | "constant": false, 1072 | "inputs": [ 1073 | { 1074 | "internalType": "bytes32", 1075 | "name": "_itemID", 1076 | "type": "bytes32" 1077 | }, 1078 | { 1079 | "internalType": "string", 1080 | "name": "_evidence", 1081 | "type": "string" 1082 | } 1083 | ], 1084 | "name": "removeItem", 1085 | "outputs": [], 1086 | "payable": true, 1087 | "stateMutability": "payable", 1088 | "type": "function" 1089 | }, 1090 | { 1091 | "constant": false, 1092 | "inputs": [ 1093 | { 1094 | "internalType": "uint256", 1095 | "name": "_disputeID", 1096 | "type": "uint256" 1097 | }, 1098 | { 1099 | "internalType": "uint256", 1100 | "name": "_ruling", 1101 | "type": "uint256" 1102 | } 1103 | ], 1104 | "name": "rule", 1105 | "outputs": [], 1106 | "payable": false, 1107 | "stateMutability": "nonpayable", 1108 | "type": "function" 1109 | }, 1110 | { 1111 | "constant": true, 1112 | "inputs": [], 1113 | "name": "sharedStakeMultiplier", 1114 | "outputs": [ 1115 | { 1116 | "internalType": "uint256", 1117 | "name": "", 1118 | "type": "uint256" 1119 | } 1120 | ], 1121 | "payable": false, 1122 | "stateMutability": "view", 1123 | "type": "function" 1124 | }, 1125 | { 1126 | "constant": true, 1127 | "inputs": [], 1128 | "name": "submissionBaseDeposit", 1129 | "outputs": [ 1130 | { 1131 | "internalType": "uint256", 1132 | "name": "", 1133 | "type": "uint256" 1134 | } 1135 | ], 1136 | "payable": false, 1137 | "stateMutability": "view", 1138 | "type": "function" 1139 | }, 1140 | { 1141 | "constant": true, 1142 | "inputs": [], 1143 | "name": "submissionChallengeBaseDeposit", 1144 | "outputs": [ 1145 | { 1146 | "internalType": "uint256", 1147 | "name": "", 1148 | "type": "uint256" 1149 | } 1150 | ], 1151 | "payable": false, 1152 | "stateMutability": "view", 1153 | "type": "function" 1154 | }, 1155 | { 1156 | "constant": false, 1157 | "inputs": [ 1158 | { 1159 | "internalType": "bytes32", 1160 | "name": "_itemID", 1161 | "type": "bytes32" 1162 | }, 1163 | { 1164 | "internalType": "string", 1165 | "name": "_evidence", 1166 | "type": "string" 1167 | } 1168 | ], 1169 | "name": "submitEvidence", 1170 | "outputs": [], 1171 | "payable": false, 1172 | "stateMutability": "nonpayable", 1173 | "type": "function" 1174 | }, 1175 | { 1176 | "constant": true, 1177 | "inputs": [], 1178 | "name": "winnerStakeMultiplier", 1179 | "outputs": [ 1180 | { 1181 | "internalType": "uint256", 1182 | "name": "", 1183 | "type": "uint256" 1184 | } 1185 | ], 1186 | "payable": false, 1187 | "stateMutability": "view", 1188 | "type": "function" 1189 | }, 1190 | { 1191 | "constant": false, 1192 | "inputs": [ 1193 | { 1194 | "internalType": "address payable", 1195 | "name": "_beneficiary", 1196 | "type": "address" 1197 | }, 1198 | { 1199 | "internalType": "bytes32", 1200 | "name": "_itemID", 1201 | "type": "bytes32" 1202 | }, 1203 | { 1204 | "internalType": "uint256", 1205 | "name": "_request", 1206 | "type": "uint256" 1207 | }, 1208 | { 1209 | "internalType": "uint256", 1210 | "name": "_round", 1211 | "type": "uint256" 1212 | } 1213 | ], 1214 | "name": "withdrawFeesAndRewards", 1215 | "outputs": [], 1216 | "payable": false, 1217 | "stateMutability": "nonpayable", 1218 | "type": "function" 1219 | } 1220 | ] 1221 | } 1222 | -------------------------------------------------------------------------------- /deployments/mainnet/GeneralizedTCRView.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0xe75a12f40Da77D285c08a44f499e597BC5085658", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [ 7 | { 8 | "internalType": "address", 9 | "name": "_address", 10 | "type": "address" 11 | }, 12 | { 13 | "internalType": "bytes32", 14 | "name": "_itemID", 15 | "type": "bytes32" 16 | }, 17 | { 18 | "internalType": "address", 19 | "name": "_contributor", 20 | "type": "address" 21 | } 22 | ], 23 | "name": "availableRewards", 24 | "outputs": [ 25 | { 26 | "internalType": "uint256", 27 | "name": "rewards", 28 | "type": "uint256" 29 | } 30 | ], 31 | "payable": false, 32 | "stateMutability": "view", 33 | "type": "function" 34 | }, 35 | { 36 | "constant": true, 37 | "inputs": [ 38 | { 39 | "internalType": "address", 40 | "name": "_address", 41 | "type": "address" 42 | }, 43 | { 44 | "internalType": "uint256", 45 | "name": "_cursorIndex", 46 | "type": "uint256" 47 | }, 48 | { 49 | "internalType": "uint256", 50 | "name": "_count", 51 | "type": "uint256" 52 | }, 53 | { 54 | "internalType": "bool[8]", 55 | "name": "_filter", 56 | "type": "bool[8]" 57 | }, 58 | { 59 | "internalType": "address", 60 | "name": "_party", 61 | "type": "address" 62 | } 63 | ], 64 | "name": "countWithFilter", 65 | "outputs": [ 66 | { 67 | "internalType": "uint256", 68 | "name": "count", 69 | "type": "uint256" 70 | }, 71 | { 72 | "internalType": "bool", 73 | "name": "hasMore", 74 | "type": "bool" 75 | }, 76 | { 77 | "internalType": "uint256", 78 | "name": "", 79 | "type": "uint256" 80 | } 81 | ], 82 | "payable": false, 83 | "stateMutability": "view", 84 | "type": "function" 85 | }, 86 | { 87 | "constant": true, 88 | "inputs": [ 89 | { 90 | "internalType": "address", 91 | "name": "_address", 92 | "type": "address" 93 | } 94 | ], 95 | "name": "fetchArbitrable", 96 | "outputs": [ 97 | { 98 | "components": [ 99 | { 100 | "internalType": "address", 101 | "name": "governor", 102 | "type": "address" 103 | }, 104 | { 105 | "internalType": "address", 106 | "name": "arbitrator", 107 | "type": "address" 108 | }, 109 | { 110 | "internalType": "bytes", 111 | "name": "arbitratorExtraData", 112 | "type": "bytes" 113 | }, 114 | { 115 | "internalType": "uint256", 116 | "name": "submissionBaseDeposit", 117 | "type": "uint256" 118 | }, 119 | { 120 | "internalType": "uint256", 121 | "name": "removalBaseDeposit", 122 | "type": "uint256" 123 | }, 124 | { 125 | "internalType": "uint256", 126 | "name": "submissionChallengeBaseDeposit", 127 | "type": "uint256" 128 | }, 129 | { 130 | "internalType": "uint256", 131 | "name": "removalChallengeBaseDeposit", 132 | "type": "uint256" 133 | }, 134 | { 135 | "internalType": "uint256", 136 | "name": "challengePeriodDuration", 137 | "type": "uint256" 138 | }, 139 | { 140 | "internalType": "uint256", 141 | "name": "metaEvidenceUpdates", 142 | "type": "uint256" 143 | }, 144 | { 145 | "internalType": "uint256", 146 | "name": "winnerStakeMultiplier", 147 | "type": "uint256" 148 | }, 149 | { 150 | "internalType": "uint256", 151 | "name": "loserStakeMultiplier", 152 | "type": "uint256" 153 | }, 154 | { 155 | "internalType": "uint256", 156 | "name": "sharedStakeMultiplier", 157 | "type": "uint256" 158 | }, 159 | { 160 | "internalType": "uint256", 161 | "name": "MULTIPLIER_DIVISOR", 162 | "type": "uint256" 163 | }, 164 | { 165 | "internalType": "uint256", 166 | "name": "arbitrationCost", 167 | "type": "uint256" 168 | } 169 | ], 170 | "internalType": "struct GeneralizedTCRView.ArbitrableData", 171 | "name": "result", 172 | "type": "tuple" 173 | } 174 | ], 175 | "payable": false, 176 | "stateMutability": "view", 177 | "type": "function" 178 | }, 179 | { 180 | "constant": true, 181 | "inputs": [ 182 | { 183 | "internalType": "address", 184 | "name": "_address", 185 | "type": "address" 186 | }, 187 | { 188 | "internalType": "uint256[4]", 189 | "name": "_targets", 190 | "type": "uint256[4]" 191 | }, 192 | { 193 | "internalType": "bool[9]", 194 | "name": "_filter", 195 | "type": "bool[9]" 196 | }, 197 | { 198 | "internalType": "address", 199 | "name": "_party", 200 | "type": "address" 201 | } 202 | ], 203 | "name": "findIndexForPage", 204 | "outputs": [ 205 | { 206 | "internalType": "uint256", 207 | "name": "index", 208 | "type": "uint256" 209 | }, 210 | { 211 | "internalType": "bool", 212 | "name": "hasMore", 213 | "type": "bool" 214 | }, 215 | { 216 | "internalType": "bool", 217 | "name": "indexFound", 218 | "type": "bool" 219 | } 220 | ], 221 | "payable": false, 222 | "stateMutability": "view", 223 | "type": "function" 224 | }, 225 | { 226 | "constant": true, 227 | "inputs": [ 228 | { 229 | "internalType": "address", 230 | "name": "_address", 231 | "type": "address" 232 | }, 233 | { 234 | "internalType": "bytes", 235 | "name": "_rlpEncodedMatch", 236 | "type": "bytes" 237 | }, 238 | { 239 | "internalType": "uint256", 240 | "name": "_cursor", 241 | "type": "uint256" 242 | }, 243 | { 244 | "internalType": "uint256", 245 | "name": "_count", 246 | "type": "uint256" 247 | }, 248 | { 249 | "internalType": "bool[4]", 250 | "name": "_skipState", 251 | "type": "bool[4]" 252 | }, 253 | { 254 | "internalType": "bool[]", 255 | "name": "_ignoreColumns", 256 | "type": "bool[]" 257 | } 258 | ], 259 | "name": "findItem", 260 | "outputs": [ 261 | { 262 | "components": [ 263 | { 264 | "internalType": "bytes32", 265 | "name": "ID", 266 | "type": "bytes32" 267 | }, 268 | { 269 | "internalType": "bytes", 270 | "name": "data", 271 | "type": "bytes" 272 | }, 273 | { 274 | "internalType": "enum GeneralizedTCR.Status", 275 | "name": "status", 276 | "type": "uint8" 277 | }, 278 | { 279 | "internalType": "bool", 280 | "name": "disputed", 281 | "type": "bool" 282 | }, 283 | { 284 | "internalType": "bool", 285 | "name": "resolved", 286 | "type": "bool" 287 | }, 288 | { 289 | "internalType": "uint256", 290 | "name": "disputeID", 291 | "type": "uint256" 292 | }, 293 | { 294 | "internalType": "uint256", 295 | "name": "appealCost", 296 | "type": "uint256" 297 | }, 298 | { 299 | "internalType": "bool", 300 | "name": "appealed", 301 | "type": "bool" 302 | }, 303 | { 304 | "internalType": "uint256", 305 | "name": "appealStart", 306 | "type": "uint256" 307 | }, 308 | { 309 | "internalType": "uint256", 310 | "name": "appealEnd", 311 | "type": "uint256" 312 | }, 313 | { 314 | "internalType": "enum GeneralizedTCR.Party", 315 | "name": "ruling", 316 | "type": "uint8" 317 | }, 318 | { 319 | "internalType": "address", 320 | "name": "requester", 321 | "type": "address" 322 | }, 323 | { 324 | "internalType": "address", 325 | "name": "challenger", 326 | "type": "address" 327 | }, 328 | { 329 | "internalType": "address", 330 | "name": "arbitrator", 331 | "type": "address" 332 | }, 333 | { 334 | "internalType": "bytes", 335 | "name": "arbitratorExtraData", 336 | "type": "bytes" 337 | }, 338 | { 339 | "internalType": "enum GeneralizedTCR.Party", 340 | "name": "currentRuling", 341 | "type": "uint8" 342 | }, 343 | { 344 | "internalType": "bool[3]", 345 | "name": "hasPaid", 346 | "type": "bool[3]" 347 | }, 348 | { 349 | "internalType": "uint256", 350 | "name": "feeRewards", 351 | "type": "uint256" 352 | }, 353 | { 354 | "internalType": "uint256", 355 | "name": "submissionTime", 356 | "type": "uint256" 357 | }, 358 | { 359 | "internalType": "uint256[3]", 360 | "name": "amountPaid", 361 | "type": "uint256[3]" 362 | }, 363 | { 364 | "internalType": "enum IArbitrator.DisputeStatus", 365 | "name": "disputeStatus", 366 | "type": "uint8" 367 | }, 368 | { 369 | "internalType": "uint256", 370 | "name": "numberOfRequests", 371 | "type": "uint256" 372 | } 373 | ], 374 | "internalType": "struct GeneralizedTCRView.QueryResult[]", 375 | "name": "results", 376 | "type": "tuple[]" 377 | } 378 | ], 379 | "payable": false, 380 | "stateMutability": "view", 381 | "type": "function" 382 | }, 383 | { 384 | "constant": true, 385 | "inputs": [ 386 | { 387 | "internalType": "address", 388 | "name": "_address", 389 | "type": "address" 390 | }, 391 | { 392 | "internalType": "bytes32", 393 | "name": "_itemID", 394 | "type": "bytes32" 395 | } 396 | ], 397 | "name": "getItem", 398 | "outputs": [ 399 | { 400 | "components": [ 401 | { 402 | "internalType": "bytes32", 403 | "name": "ID", 404 | "type": "bytes32" 405 | }, 406 | { 407 | "internalType": "bytes", 408 | "name": "data", 409 | "type": "bytes" 410 | }, 411 | { 412 | "internalType": "enum GeneralizedTCR.Status", 413 | "name": "status", 414 | "type": "uint8" 415 | }, 416 | { 417 | "internalType": "bool", 418 | "name": "disputed", 419 | "type": "bool" 420 | }, 421 | { 422 | "internalType": "bool", 423 | "name": "resolved", 424 | "type": "bool" 425 | }, 426 | { 427 | "internalType": "uint256", 428 | "name": "disputeID", 429 | "type": "uint256" 430 | }, 431 | { 432 | "internalType": "uint256", 433 | "name": "appealCost", 434 | "type": "uint256" 435 | }, 436 | { 437 | "internalType": "bool", 438 | "name": "appealed", 439 | "type": "bool" 440 | }, 441 | { 442 | "internalType": "uint256", 443 | "name": "appealStart", 444 | "type": "uint256" 445 | }, 446 | { 447 | "internalType": "uint256", 448 | "name": "appealEnd", 449 | "type": "uint256" 450 | }, 451 | { 452 | "internalType": "enum GeneralizedTCR.Party", 453 | "name": "ruling", 454 | "type": "uint8" 455 | }, 456 | { 457 | "internalType": "address", 458 | "name": "requester", 459 | "type": "address" 460 | }, 461 | { 462 | "internalType": "address", 463 | "name": "challenger", 464 | "type": "address" 465 | }, 466 | { 467 | "internalType": "address", 468 | "name": "arbitrator", 469 | "type": "address" 470 | }, 471 | { 472 | "internalType": "bytes", 473 | "name": "arbitratorExtraData", 474 | "type": "bytes" 475 | }, 476 | { 477 | "internalType": "enum GeneralizedTCR.Party", 478 | "name": "currentRuling", 479 | "type": "uint8" 480 | }, 481 | { 482 | "internalType": "bool[3]", 483 | "name": "hasPaid", 484 | "type": "bool[3]" 485 | }, 486 | { 487 | "internalType": "uint256", 488 | "name": "feeRewards", 489 | "type": "uint256" 490 | }, 491 | { 492 | "internalType": "uint256", 493 | "name": "submissionTime", 494 | "type": "uint256" 495 | }, 496 | { 497 | "internalType": "uint256[3]", 498 | "name": "amountPaid", 499 | "type": "uint256[3]" 500 | }, 501 | { 502 | "internalType": "enum IArbitrator.DisputeStatus", 503 | "name": "disputeStatus", 504 | "type": "uint8" 505 | }, 506 | { 507 | "internalType": "uint256", 508 | "name": "numberOfRequests", 509 | "type": "uint256" 510 | } 511 | ], 512 | "internalType": "struct GeneralizedTCRView.QueryResult", 513 | "name": "result", 514 | "type": "tuple" 515 | } 516 | ], 517 | "payable": false, 518 | "stateMutability": "view", 519 | "type": "function" 520 | }, 521 | { 522 | "constant": true, 523 | "inputs": [ 524 | { 525 | "internalType": "address", 526 | "name": "_address", 527 | "type": "address" 528 | }, 529 | { 530 | "internalType": "bytes32", 531 | "name": "_itemID", 532 | "type": "bytes32" 533 | } 534 | ], 535 | "name": "getItemData", 536 | "outputs": [ 537 | { 538 | "components": [ 539 | { 540 | "internalType": "bytes", 541 | "name": "data", 542 | "type": "bytes" 543 | }, 544 | { 545 | "internalType": "enum GeneralizedTCR.Status", 546 | "name": "status", 547 | "type": "uint8" 548 | }, 549 | { 550 | "internalType": "uint256", 551 | "name": "numberOfRequests", 552 | "type": "uint256" 553 | } 554 | ], 555 | "internalType": "struct GeneralizedTCRView.ItemData", 556 | "name": "item", 557 | "type": "tuple" 558 | } 559 | ], 560 | "payable": false, 561 | "stateMutability": "view", 562 | "type": "function" 563 | }, 564 | { 565 | "constant": true, 566 | "inputs": [ 567 | { 568 | "internalType": "address", 569 | "name": "_address", 570 | "type": "address" 571 | }, 572 | { 573 | "internalType": "bytes32", 574 | "name": "_itemID", 575 | "type": "bytes32" 576 | } 577 | ], 578 | "name": "getItemRequests", 579 | "outputs": [ 580 | { 581 | "components": [ 582 | { 583 | "internalType": "bool", 584 | "name": "disputed", 585 | "type": "bool" 586 | }, 587 | { 588 | "internalType": "uint256", 589 | "name": "disputeID", 590 | "type": "uint256" 591 | }, 592 | { 593 | "internalType": "uint256", 594 | "name": "submissionTime", 595 | "type": "uint256" 596 | }, 597 | { 598 | "internalType": "bool", 599 | "name": "resolved", 600 | "type": "bool" 601 | }, 602 | { 603 | "internalType": "address", 604 | "name": "requester", 605 | "type": "address" 606 | }, 607 | { 608 | "internalType": "address", 609 | "name": "challenger", 610 | "type": "address" 611 | }, 612 | { 613 | "internalType": "address", 614 | "name": "arbitrator", 615 | "type": "address" 616 | }, 617 | { 618 | "internalType": "bytes", 619 | "name": "arbitratorExtraData", 620 | "type": "bytes" 621 | }, 622 | { 623 | "internalType": "uint256", 624 | "name": "metaEvidenceID", 625 | "type": "uint256" 626 | } 627 | ], 628 | "internalType": "struct GeneralizedTCRView.ItemRequest[]", 629 | "name": "requests", 630 | "type": "tuple[]" 631 | } 632 | ], 633 | "payable": false, 634 | "stateMutability": "view", 635 | "type": "function" 636 | }, 637 | { 638 | "constant": true, 639 | "inputs": [ 640 | { 641 | "internalType": "address", 642 | "name": "_address", 643 | "type": "address" 644 | }, 645 | { 646 | "internalType": "bytes32", 647 | "name": "_itemID", 648 | "type": "bytes32" 649 | } 650 | ], 651 | "name": "getLatestRequestData", 652 | "outputs": [ 653 | { 654 | "components": [ 655 | { 656 | "components": [ 657 | { 658 | "internalType": "bytes", 659 | "name": "data", 660 | "type": "bytes" 661 | }, 662 | { 663 | "internalType": "enum GeneralizedTCR.Status", 664 | "name": "status", 665 | "type": "uint8" 666 | }, 667 | { 668 | "internalType": "uint256", 669 | "name": "numberOfRequests", 670 | "type": "uint256" 671 | } 672 | ], 673 | "internalType": "struct GeneralizedTCRView.ItemData", 674 | "name": "item", 675 | "type": "tuple" 676 | }, 677 | { 678 | "internalType": "bool", 679 | "name": "disputed", 680 | "type": "bool" 681 | }, 682 | { 683 | "internalType": "uint256", 684 | "name": "disputeID", 685 | "type": "uint256" 686 | }, 687 | { 688 | "internalType": "uint256", 689 | "name": "submissionTime", 690 | "type": "uint256" 691 | }, 692 | { 693 | "internalType": "bool", 694 | "name": "resolved", 695 | "type": "bool" 696 | }, 697 | { 698 | "internalType": "address payable[3]", 699 | "name": "parties", 700 | "type": "address[3]" 701 | }, 702 | { 703 | "internalType": "uint256", 704 | "name": "numberOfRounds", 705 | "type": "uint256" 706 | }, 707 | { 708 | "internalType": "enum GeneralizedTCR.Party", 709 | "name": "ruling", 710 | "type": "uint8" 711 | }, 712 | { 713 | "internalType": "contract IArbitrator", 714 | "name": "arbitrator", 715 | "type": "address" 716 | }, 717 | { 718 | "internalType": "bytes", 719 | "name": "arbitratorExtraData", 720 | "type": "bytes" 721 | } 722 | ], 723 | "internalType": "struct GeneralizedTCRView.RequestData", 724 | "name": "request", 725 | "type": "tuple" 726 | } 727 | ], 728 | "payable": false, 729 | "stateMutability": "view", 730 | "type": "function" 731 | }, 732 | { 733 | "constant": true, 734 | "inputs": [ 735 | { 736 | "internalType": "address", 737 | "name": "_address", 738 | "type": "address" 739 | }, 740 | { 741 | "internalType": "bytes32", 742 | "name": "_itemID", 743 | "type": "bytes32" 744 | } 745 | ], 746 | "name": "getLatestRoundRequestData", 747 | "outputs": [ 748 | { 749 | "components": [ 750 | { 751 | "components": [ 752 | { 753 | "components": [ 754 | { 755 | "internalType": "bytes", 756 | "name": "data", 757 | "type": "bytes" 758 | }, 759 | { 760 | "internalType": "enum GeneralizedTCR.Status", 761 | "name": "status", 762 | "type": "uint8" 763 | }, 764 | { 765 | "internalType": "uint256", 766 | "name": "numberOfRequests", 767 | "type": "uint256" 768 | } 769 | ], 770 | "internalType": "struct GeneralizedTCRView.ItemData", 771 | "name": "item", 772 | "type": "tuple" 773 | }, 774 | { 775 | "internalType": "bool", 776 | "name": "disputed", 777 | "type": "bool" 778 | }, 779 | { 780 | "internalType": "uint256", 781 | "name": "disputeID", 782 | "type": "uint256" 783 | }, 784 | { 785 | "internalType": "uint256", 786 | "name": "submissionTime", 787 | "type": "uint256" 788 | }, 789 | { 790 | "internalType": "bool", 791 | "name": "resolved", 792 | "type": "bool" 793 | }, 794 | { 795 | "internalType": "address payable[3]", 796 | "name": "parties", 797 | "type": "address[3]" 798 | }, 799 | { 800 | "internalType": "uint256", 801 | "name": "numberOfRounds", 802 | "type": "uint256" 803 | }, 804 | { 805 | "internalType": "enum GeneralizedTCR.Party", 806 | "name": "ruling", 807 | "type": "uint8" 808 | }, 809 | { 810 | "internalType": "contract IArbitrator", 811 | "name": "arbitrator", 812 | "type": "address" 813 | }, 814 | { 815 | "internalType": "bytes", 816 | "name": "arbitratorExtraData", 817 | "type": "bytes" 818 | } 819 | ], 820 | "internalType": "struct GeneralizedTCRView.RequestData", 821 | "name": "request", 822 | "type": "tuple" 823 | }, 824 | { 825 | "internalType": "bool", 826 | "name": "appealed", 827 | "type": "bool" 828 | }, 829 | { 830 | "internalType": "uint256[3]", 831 | "name": "amountPaid", 832 | "type": "uint256[3]" 833 | }, 834 | { 835 | "internalType": "bool[3]", 836 | "name": "hasPaid", 837 | "type": "bool[3]" 838 | }, 839 | { 840 | "internalType": "uint256", 841 | "name": "feeRewards", 842 | "type": "uint256" 843 | } 844 | ], 845 | "internalType": "struct GeneralizedTCRView.RoundData", 846 | "name": "round", 847 | "type": "tuple" 848 | } 849 | ], 850 | "payable": false, 851 | "stateMutability": "view", 852 | "type": "function" 853 | }, 854 | { 855 | "constant": true, 856 | "inputs": [ 857 | { 858 | "internalType": "address", 859 | "name": "_address", 860 | "type": "address" 861 | }, 862 | { 863 | "internalType": "uint256", 864 | "name": "_cursorIndex", 865 | "type": "uint256" 866 | }, 867 | { 868 | "internalType": "uint256", 869 | "name": "_count", 870 | "type": "uint256" 871 | }, 872 | { 873 | "internalType": "bool[8]", 874 | "name": "_filter", 875 | "type": "bool[8]" 876 | }, 877 | { 878 | "internalType": "bool", 879 | "name": "_oldestFirst", 880 | "type": "bool" 881 | }, 882 | { 883 | "internalType": "address", 884 | "name": "_party", 885 | "type": "address" 886 | }, 887 | { 888 | "internalType": "uint256", 889 | "name": "_limit", 890 | "type": "uint256" 891 | } 892 | ], 893 | "name": "queryItems", 894 | "outputs": [ 895 | { 896 | "components": [ 897 | { 898 | "internalType": "bytes32", 899 | "name": "ID", 900 | "type": "bytes32" 901 | }, 902 | { 903 | "internalType": "bytes", 904 | "name": "data", 905 | "type": "bytes" 906 | }, 907 | { 908 | "internalType": "enum GeneralizedTCR.Status", 909 | "name": "status", 910 | "type": "uint8" 911 | }, 912 | { 913 | "internalType": "bool", 914 | "name": "disputed", 915 | "type": "bool" 916 | }, 917 | { 918 | "internalType": "bool", 919 | "name": "resolved", 920 | "type": "bool" 921 | }, 922 | { 923 | "internalType": "uint256", 924 | "name": "disputeID", 925 | "type": "uint256" 926 | }, 927 | { 928 | "internalType": "uint256", 929 | "name": "appealCost", 930 | "type": "uint256" 931 | }, 932 | { 933 | "internalType": "bool", 934 | "name": "appealed", 935 | "type": "bool" 936 | }, 937 | { 938 | "internalType": "uint256", 939 | "name": "appealStart", 940 | "type": "uint256" 941 | }, 942 | { 943 | "internalType": "uint256", 944 | "name": "appealEnd", 945 | "type": "uint256" 946 | }, 947 | { 948 | "internalType": "enum GeneralizedTCR.Party", 949 | "name": "ruling", 950 | "type": "uint8" 951 | }, 952 | { 953 | "internalType": "address", 954 | "name": "requester", 955 | "type": "address" 956 | }, 957 | { 958 | "internalType": "address", 959 | "name": "challenger", 960 | "type": "address" 961 | }, 962 | { 963 | "internalType": "address", 964 | "name": "arbitrator", 965 | "type": "address" 966 | }, 967 | { 968 | "internalType": "bytes", 969 | "name": "arbitratorExtraData", 970 | "type": "bytes" 971 | }, 972 | { 973 | "internalType": "enum GeneralizedTCR.Party", 974 | "name": "currentRuling", 975 | "type": "uint8" 976 | }, 977 | { 978 | "internalType": "bool[3]", 979 | "name": "hasPaid", 980 | "type": "bool[3]" 981 | }, 982 | { 983 | "internalType": "uint256", 984 | "name": "feeRewards", 985 | "type": "uint256" 986 | }, 987 | { 988 | "internalType": "uint256", 989 | "name": "submissionTime", 990 | "type": "uint256" 991 | }, 992 | { 993 | "internalType": "uint256[3]", 994 | "name": "amountPaid", 995 | "type": "uint256[3]" 996 | }, 997 | { 998 | "internalType": "enum IArbitrator.DisputeStatus", 999 | "name": "disputeStatus", 1000 | "type": "uint8" 1001 | }, 1002 | { 1003 | "internalType": "uint256", 1004 | "name": "numberOfRequests", 1005 | "type": "uint256" 1006 | } 1007 | ], 1008 | "internalType": "struct GeneralizedTCRView.QueryResult[]", 1009 | "name": "results", 1010 | "type": "tuple[]" 1011 | }, 1012 | { 1013 | "internalType": "bool", 1014 | "name": "hasMore", 1015 | "type": "bool" 1016 | } 1017 | ], 1018 | "payable": false, 1019 | "stateMutability": "view", 1020 | "type": "function" 1021 | } 1022 | ] 1023 | } 1024 | -------------------------------------------------------------------------------- /deployments/mainnet/LightGeneralizedTCRView.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0xe82a69e939e1aB6Dc1868262cfe444F70098cCC8", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [ 7 | { 8 | "internalType": "address", 9 | "name": "_address", 10 | "type": "address" 11 | }, 12 | { 13 | "internalType": "bytes32", 14 | "name": "_itemID", 15 | "type": "bytes32" 16 | }, 17 | { 18 | "internalType": "address", 19 | "name": "_contributor", 20 | "type": "address" 21 | } 22 | ], 23 | "name": "availableRewards", 24 | "outputs": [ 25 | { 26 | "internalType": "uint256", 27 | "name": "rewards", 28 | "type": "uint256" 29 | } 30 | ], 31 | "payable": false, 32 | "stateMutability": "view", 33 | "type": "function" 34 | }, 35 | { 36 | "constant": true, 37 | "inputs": [ 38 | { 39 | "internalType": "address", 40 | "name": "_address", 41 | "type": "address" 42 | } 43 | ], 44 | "name": "fetchArbitrable", 45 | "outputs": [ 46 | { 47 | "components": [ 48 | { 49 | "internalType": "address", 50 | "name": "governor", 51 | "type": "address" 52 | }, 53 | { 54 | "internalType": "address", 55 | "name": "arbitrator", 56 | "type": "address" 57 | }, 58 | { 59 | "internalType": "bytes", 60 | "name": "arbitratorExtraData", 61 | "type": "bytes" 62 | }, 63 | { 64 | "internalType": "uint256", 65 | "name": "submissionBaseDeposit", 66 | "type": "uint256" 67 | }, 68 | { 69 | "internalType": "uint256", 70 | "name": "removalBaseDeposit", 71 | "type": "uint256" 72 | }, 73 | { 74 | "internalType": "uint256", 75 | "name": "submissionChallengeBaseDeposit", 76 | "type": "uint256" 77 | }, 78 | { 79 | "internalType": "uint256", 80 | "name": "removalChallengeBaseDeposit", 81 | "type": "uint256" 82 | }, 83 | { 84 | "internalType": "uint256", 85 | "name": "challengePeriodDuration", 86 | "type": "uint256" 87 | }, 88 | { 89 | "internalType": "uint256", 90 | "name": "metaEvidenceUpdates", 91 | "type": "uint256" 92 | }, 93 | { 94 | "internalType": "uint256", 95 | "name": "winnerStakeMultiplier", 96 | "type": "uint256" 97 | }, 98 | { 99 | "internalType": "uint256", 100 | "name": "loserStakeMultiplier", 101 | "type": "uint256" 102 | }, 103 | { 104 | "internalType": "uint256", 105 | "name": "sharedStakeMultiplier", 106 | "type": "uint256" 107 | }, 108 | { 109 | "internalType": "uint256", 110 | "name": "MULTIPLIER_DIVISOR", 111 | "type": "uint256" 112 | }, 113 | { 114 | "internalType": "uint256", 115 | "name": "arbitrationCost", 116 | "type": "uint256" 117 | } 118 | ], 119 | "internalType": "struct LightGeneralizedTCRView.ArbitrableData", 120 | "name": "result", 121 | "type": "tuple" 122 | } 123 | ], 124 | "payable": false, 125 | "stateMutability": "view", 126 | "type": "function" 127 | }, 128 | { 129 | "constant": true, 130 | "inputs": [ 131 | { 132 | "internalType": "address", 133 | "name": "_address", 134 | "type": "address" 135 | }, 136 | { 137 | "internalType": "bytes32", 138 | "name": "_itemID", 139 | "type": "bytes32" 140 | } 141 | ], 142 | "name": "getItem", 143 | "outputs": [ 144 | { 145 | "components": [ 146 | { 147 | "internalType": "bytes32", 148 | "name": "ID", 149 | "type": "bytes32" 150 | }, 151 | { 152 | "internalType": "enum ILightGeneralizedTCR.Status", 153 | "name": "status", 154 | "type": "uint8" 155 | }, 156 | { 157 | "internalType": "bool", 158 | "name": "disputed", 159 | "type": "bool" 160 | }, 161 | { 162 | "internalType": "bool", 163 | "name": "resolved", 164 | "type": "bool" 165 | }, 166 | { 167 | "internalType": "uint256", 168 | "name": "disputeID", 169 | "type": "uint256" 170 | }, 171 | { 172 | "internalType": "uint256", 173 | "name": "appealCost", 174 | "type": "uint256" 175 | }, 176 | { 177 | "internalType": "bool", 178 | "name": "appealed", 179 | "type": "bool" 180 | }, 181 | { 182 | "internalType": "uint256", 183 | "name": "appealStart", 184 | "type": "uint256" 185 | }, 186 | { 187 | "internalType": "uint256", 188 | "name": "appealEnd", 189 | "type": "uint256" 190 | }, 191 | { 192 | "internalType": "enum ILightGeneralizedTCR.Party", 193 | "name": "ruling", 194 | "type": "uint8" 195 | }, 196 | { 197 | "internalType": "address", 198 | "name": "requester", 199 | "type": "address" 200 | }, 201 | { 202 | "internalType": "address", 203 | "name": "challenger", 204 | "type": "address" 205 | }, 206 | { 207 | "internalType": "address", 208 | "name": "arbitrator", 209 | "type": "address" 210 | }, 211 | { 212 | "internalType": "bytes", 213 | "name": "arbitratorExtraData", 214 | "type": "bytes" 215 | }, 216 | { 217 | "internalType": "enum ILightGeneralizedTCR.Party", 218 | "name": "currentRuling", 219 | "type": "uint8" 220 | }, 221 | { 222 | "internalType": "bool[3]", 223 | "name": "hasPaid", 224 | "type": "bool[3]" 225 | }, 226 | { 227 | "internalType": "uint256", 228 | "name": "feeRewards", 229 | "type": "uint256" 230 | }, 231 | { 232 | "internalType": "uint256", 233 | "name": "submissionTime", 234 | "type": "uint256" 235 | }, 236 | { 237 | "internalType": "uint256[3]", 238 | "name": "amountPaid", 239 | "type": "uint256[3]" 240 | }, 241 | { 242 | "internalType": "enum IArbitrator.DisputeStatus", 243 | "name": "disputeStatus", 244 | "type": "uint8" 245 | }, 246 | { 247 | "internalType": "uint256", 248 | "name": "numberOfRequests", 249 | "type": "uint256" 250 | } 251 | ], 252 | "internalType": "struct LightGeneralizedTCRView.QueryResult", 253 | "name": "result", 254 | "type": "tuple" 255 | } 256 | ], 257 | "payable": false, 258 | "stateMutability": "view", 259 | "type": "function" 260 | }, 261 | { 262 | "constant": true, 263 | "inputs": [ 264 | { 265 | "internalType": "address", 266 | "name": "_address", 267 | "type": "address" 268 | }, 269 | { 270 | "internalType": "bytes32", 271 | "name": "_itemID", 272 | "type": "bytes32" 273 | } 274 | ], 275 | "name": "getItemData", 276 | "outputs": [ 277 | { 278 | "components": [ 279 | { 280 | "internalType": "enum ILightGeneralizedTCR.Status", 281 | "name": "status", 282 | "type": "uint8" 283 | }, 284 | { 285 | "internalType": "uint256", 286 | "name": "numberOfRequests", 287 | "type": "uint256" 288 | } 289 | ], 290 | "internalType": "struct LightGeneralizedTCRView.ItemData", 291 | "name": "item", 292 | "type": "tuple" 293 | } 294 | ], 295 | "payable": false, 296 | "stateMutability": "view", 297 | "type": "function" 298 | }, 299 | { 300 | "constant": true, 301 | "inputs": [ 302 | { 303 | "internalType": "address", 304 | "name": "_address", 305 | "type": "address" 306 | }, 307 | { 308 | "internalType": "bytes32", 309 | "name": "_itemID", 310 | "type": "bytes32" 311 | } 312 | ], 313 | "name": "getItemRequests", 314 | "outputs": [ 315 | { 316 | "components": [ 317 | { 318 | "internalType": "bool", 319 | "name": "disputed", 320 | "type": "bool" 321 | }, 322 | { 323 | "internalType": "uint256", 324 | "name": "disputeID", 325 | "type": "uint256" 326 | }, 327 | { 328 | "internalType": "uint256", 329 | "name": "submissionTime", 330 | "type": "uint256" 331 | }, 332 | { 333 | "internalType": "bool", 334 | "name": "resolved", 335 | "type": "bool" 336 | }, 337 | { 338 | "internalType": "address", 339 | "name": "requester", 340 | "type": "address" 341 | }, 342 | { 343 | "internalType": "address", 344 | "name": "challenger", 345 | "type": "address" 346 | }, 347 | { 348 | "internalType": "address", 349 | "name": "arbitrator", 350 | "type": "address" 351 | }, 352 | { 353 | "internalType": "bytes", 354 | "name": "arbitratorExtraData", 355 | "type": "bytes" 356 | }, 357 | { 358 | "internalType": "uint256", 359 | "name": "metaEvidenceID", 360 | "type": "uint256" 361 | } 362 | ], 363 | "internalType": "struct LightGeneralizedTCRView.ItemRequest[]", 364 | "name": "requests", 365 | "type": "tuple[]" 366 | } 367 | ], 368 | "payable": false, 369 | "stateMutability": "view", 370 | "type": "function" 371 | }, 372 | { 373 | "constant": true, 374 | "inputs": [ 375 | { 376 | "internalType": "address", 377 | "name": "_address", 378 | "type": "address" 379 | }, 380 | { 381 | "internalType": "bytes32", 382 | "name": "_itemID", 383 | "type": "bytes32" 384 | } 385 | ], 386 | "name": "getLatestRequestData", 387 | "outputs": [ 388 | { 389 | "components": [ 390 | { 391 | "components": [ 392 | { 393 | "internalType": "enum ILightGeneralizedTCR.Status", 394 | "name": "status", 395 | "type": "uint8" 396 | }, 397 | { 398 | "internalType": "uint256", 399 | "name": "numberOfRequests", 400 | "type": "uint256" 401 | } 402 | ], 403 | "internalType": "struct LightGeneralizedTCRView.ItemData", 404 | "name": "item", 405 | "type": "tuple" 406 | }, 407 | { 408 | "internalType": "bool", 409 | "name": "disputed", 410 | "type": "bool" 411 | }, 412 | { 413 | "internalType": "uint256", 414 | "name": "disputeID", 415 | "type": "uint256" 416 | }, 417 | { 418 | "internalType": "uint256", 419 | "name": "submissionTime", 420 | "type": "uint256" 421 | }, 422 | { 423 | "internalType": "bool", 424 | "name": "resolved", 425 | "type": "bool" 426 | }, 427 | { 428 | "internalType": "address payable[3]", 429 | "name": "parties", 430 | "type": "address[3]" 431 | }, 432 | { 433 | "internalType": "uint256", 434 | "name": "numberOfRounds", 435 | "type": "uint256" 436 | }, 437 | { 438 | "internalType": "enum ILightGeneralizedTCR.Party", 439 | "name": "ruling", 440 | "type": "uint8" 441 | }, 442 | { 443 | "internalType": "contract IArbitrator", 444 | "name": "arbitrator", 445 | "type": "address" 446 | }, 447 | { 448 | "internalType": "bytes", 449 | "name": "arbitratorExtraData", 450 | "type": "bytes" 451 | } 452 | ], 453 | "internalType": "struct LightGeneralizedTCRView.RequestData", 454 | "name": "request", 455 | "type": "tuple" 456 | } 457 | ], 458 | "payable": false, 459 | "stateMutability": "view", 460 | "type": "function" 461 | }, 462 | { 463 | "constant": true, 464 | "inputs": [ 465 | { 466 | "internalType": "address", 467 | "name": "_address", 468 | "type": "address" 469 | }, 470 | { 471 | "internalType": "bytes32", 472 | "name": "_itemID", 473 | "type": "bytes32" 474 | } 475 | ], 476 | "name": "getLatestRoundRequestData", 477 | "outputs": [ 478 | { 479 | "components": [ 480 | { 481 | "components": [ 482 | { 483 | "components": [ 484 | { 485 | "internalType": "enum ILightGeneralizedTCR.Status", 486 | "name": "status", 487 | "type": "uint8" 488 | }, 489 | { 490 | "internalType": "uint256", 491 | "name": "numberOfRequests", 492 | "type": "uint256" 493 | } 494 | ], 495 | "internalType": "struct LightGeneralizedTCRView.ItemData", 496 | "name": "item", 497 | "type": "tuple" 498 | }, 499 | { 500 | "internalType": "bool", 501 | "name": "disputed", 502 | "type": "bool" 503 | }, 504 | { 505 | "internalType": "uint256", 506 | "name": "disputeID", 507 | "type": "uint256" 508 | }, 509 | { 510 | "internalType": "uint256", 511 | "name": "submissionTime", 512 | "type": "uint256" 513 | }, 514 | { 515 | "internalType": "bool", 516 | "name": "resolved", 517 | "type": "bool" 518 | }, 519 | { 520 | "internalType": "address payable[3]", 521 | "name": "parties", 522 | "type": "address[3]" 523 | }, 524 | { 525 | "internalType": "uint256", 526 | "name": "numberOfRounds", 527 | "type": "uint256" 528 | }, 529 | { 530 | "internalType": "enum ILightGeneralizedTCR.Party", 531 | "name": "ruling", 532 | "type": "uint8" 533 | }, 534 | { 535 | "internalType": "contract IArbitrator", 536 | "name": "arbitrator", 537 | "type": "address" 538 | }, 539 | { 540 | "internalType": "bytes", 541 | "name": "arbitratorExtraData", 542 | "type": "bytes" 543 | } 544 | ], 545 | "internalType": "struct LightGeneralizedTCRView.RequestData", 546 | "name": "request", 547 | "type": "tuple" 548 | }, 549 | { 550 | "internalType": "bool", 551 | "name": "appealed", 552 | "type": "bool" 553 | }, 554 | { 555 | "internalType": "uint256[3]", 556 | "name": "amountPaid", 557 | "type": "uint256[3]" 558 | }, 559 | { 560 | "internalType": "bool[3]", 561 | "name": "hasPaid", 562 | "type": "bool[3]" 563 | }, 564 | { 565 | "internalType": "uint256", 566 | "name": "feeRewards", 567 | "type": "uint256" 568 | } 569 | ], 570 | "internalType": "struct LightGeneralizedTCRView.RoundData", 571 | "name": "round", 572 | "type": "tuple" 573 | } 574 | ], 575 | "payable": false, 576 | "stateMutability": "view", 577 | "type": "function" 578 | } 579 | ] 580 | } 581 | -------------------------------------------------------------------------------- /deployments/mumbai/.chainId: -------------------------------------------------------------------------------- 1 | 80001 -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require("@nomiclabs/hardhat-web3"); 3 | require("hardhat-gas-reporter"); 4 | require("@nomiclabs/hardhat-ethers"); 5 | require("hardhat-deploy"); 6 | module.exports = { 7 | solidity: { 8 | version: "0.5.17", 9 | settings: { 10 | optimizer: { 11 | enabled: true, 12 | runs: 200, 13 | }, 14 | }, 15 | }, 16 | networks: { 17 | hardhat: { 18 | live: false, 19 | saveDeployments: true, 20 | allowUnlimitedContractSize: true, 21 | tags: ["test", "local"], 22 | }, 23 | localhost: { 24 | url: `http://127.0.0.1:8545`, 25 | chainId: 31337, 26 | saveDeployments: true, 27 | tags: ["test", "local"], 28 | }, 29 | mumbai: { 30 | live: false, 31 | saveDeployments: true, 32 | tags: ["test", "local"], 33 | url: `https://matic-mumbai.chainstacklabs.com`, 34 | chainId: 80001, 35 | accounts: 36 | process.env.PRIVATE_KEY_GOVERNOR !== undefined && process.env.PRIVATE_KEY_DEPLOYER !== undefined 37 | ? [process.env.PRIVATE_KEY_GOVERNOR, process.env.PRIVATE_KEY_DEPLOYER] 38 | : [], 39 | etherscan: { 40 | apiKey: process.env.POLYGONSCAN_API_KEY, 41 | }, 42 | }, 43 | goerli: { 44 | chainId: 5, 45 | url: `https://goerli.infura.io/v3/${process.env.INFURA_API_KEY}`, 46 | accounts: 47 | process.env.PRIVATE_KEY_GOVERNOR !== undefined && process.env.PRIVATE_KEY_DEPLOYER !== undefined 48 | ? [process.env.PRIVATE_KEY_GOVERNOR, process.env.PRIVATE_KEY_DEPLOYER] 49 | : [], 50 | live: true, 51 | saveDeployments: true, 52 | tags: ["staging", "foreign", "layer1"], 53 | }, 54 | mainnet: { 55 | chainId: 1, 56 | url: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, 57 | accounts: 58 | process.env.PRIVATE_KEY_GOVERNOR !== undefined && process.env.PRIVATE_KEY_DEPLOYER !== undefined 59 | ? [process.env.PRIVATE_KEY_GOVERNOR, process.env.PRIVATE_KEY_DEPLOYER] 60 | : [], 61 | live: true, 62 | saveDeployments: true, 63 | tags: ["production", "foreign", "layer1"], 64 | }, 65 | }, 66 | namedAccounts: { 67 | governor: { 68 | default: 0, 69 | }, 70 | requester: { 71 | default: 1, 72 | }, 73 | challenger: { 74 | default: 2, 75 | }, 76 | governor2: { 77 | default: 3, 78 | }, 79 | other: { 80 | default: 4, 81 | }, 82 | deployer: { 83 | default: 5, 84 | }, 85 | }, 86 | 87 | gasReporter: { 88 | enabled: process.env.REPORT_GAS ? true : false, 89 | coinmarketcap: process.env.COINMARKETCAP_API_KEY, 90 | currency: "USD", 91 | gasPrice: 100, 92 | }, 93 | verify: { 94 | etherscan: { 95 | apiKey: process.env.ETHERSCAN_API_KEY, 96 | }, 97 | }, 98 | }; 99 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kleros/tcr", 3 | "version": "2.0.0", 4 | "description": "Arbitrable Permission Lists on Ethereum", 5 | "repository": "https://github.com/kleros/tcr", 6 | "author": "Kleros", 7 | "license": "MIT", 8 | "private": false, 9 | "scripts": { 10 | "test": "hardhat test", 11 | "build": "hardhat compile", 12 | "prepare": "husky install" 13 | }, 14 | "files": [ 15 | "artifacts/**/*.json", 16 | "contracts/*.sol", 17 | "contracts/view/*.sol", 18 | "contracts/utils/*.sol" 19 | ], 20 | "commitlint": { 21 | "extends": [ 22 | "@commitlint/config-conventional" 23 | ] 24 | }, 25 | "devDependencies": { 26 | "@kleros/kathari": "^0.23.0", 27 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", 28 | "@nomiclabs/hardhat-truffle5": "^2.0.2", 29 | "@nomiclabs/hardhat-waffle": "^2.0.1", 30 | "@nomiclabs/hardhat-web3": "^2.0.0", 31 | "@openzeppelin/test-helpers": "^0.5.13", 32 | "chai": "^4.3.4", 33 | "eslint": "^7.32.0", 34 | "eslint-config-prettier": "^8.3.0", 35 | "eslint-plugin-import": "^2.24.2", 36 | "eslint-plugin-prettier": "^4.0.0", 37 | "ethereum-waffle": "^3.4.0", 38 | "ethers": "^5.7.2", 39 | "ganache-cli": "^6.4.4", 40 | "hardhat": "^2.11.1", 41 | "hardhat-gas-reporter": "^1.0.4", 42 | "husky": "^7.0.0", 43 | "jsonfile": "^5.0.0", 44 | "lint-staged": "^11.2.0", 45 | "npm-run-all": "^4.1.5", 46 | "prettier": "^2.4.1", 47 | "prettier-plugin-solidity": "^1.0.0-beta.18", 48 | "solhint": "^3.3.6", 49 | "solhint-plugin-prettier": "^0.0.5", 50 | "standard-version": "^8.0.1", 51 | "truffle": "^5.0.25", 52 | "web3": "~1.5.0", 53 | "web3-utils": "~1.5.0" 54 | }, 55 | "dependencies": { 56 | "@kleros/erc-792": "3.0.0", 57 | "bn.js": "^5.2.1", 58 | "hardhat-deploy": "^0.11.20", 59 | "solidity-bytes-utils": "^0.0.8", 60 | "solidity-rlp": "^2.0.1" 61 | }, 62 | "volta": { 63 | "node": "14.18.0", 64 | "yarn": "1.22.11" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /test/light-gtcr-factory.js: -------------------------------------------------------------------------------- 1 | const { deployments, ethers } = require("hardhat"); 2 | const { expect } = require("chai"); 3 | const { expectRevert } = require("@openzeppelin/test-helpers"); 4 | const { BN } = require("bn.js"); 5 | 6 | describe("LightGTCRFactory", async () => { 7 | let governor; 8 | let other; 9 | let arbitratorExtraData; 10 | let arbitrationCost; 11 | const submissionBaseDeposit = 2000; 12 | const removalBaseDeposit = 1300; 13 | const submissionChallengeBaseDeposit = 5000; 14 | const removalChallengeBaseDeposit = 1200; 15 | const challengePeriodDuration = 600; 16 | const sharedStakeMultiplier = 5000; 17 | const winnerStakeMultiplier = 2000; 18 | const loserStakeMultiplier = 8000; 19 | const registrationMetaEvidence = "registrationMetaEvidence.json"; 20 | const clearingMetaEvidence = "clearingMetaEvidence.json"; 21 | 22 | let arbitrator; 23 | let factory; 24 | let gtcr; 25 | let relay; 26 | 27 | before("Get accounts", async () => { 28 | [governor, , , , other] = await ethers.getSigners(); 29 | arbitratorExtraData = "0x85"; 30 | arbitrationCost = 1000; 31 | }); 32 | beforeEach("setup contract", async function () { 33 | await deployments.fixture(["gtcrContracts"], { 34 | fallbackToGlobal: true, 35 | keepExistingDeployments: false, 36 | }); 37 | arbitrator = await ethers.getContract("EnhancedAppealableArbitrator"); 38 | relay = await ethers.getContract("RelayMock"); 39 | 40 | await arbitrator.connect(governor).changeArbitrator(arbitrator.address); 41 | 42 | await arbitrator.connect(other).createDispute(3, arbitratorExtraData, { 43 | value: arbitrationCost, 44 | }); // Create a dispute so the index in tests will not be a default value. 45 | factory = await ethers.getContract("LightGTCRFactory"); 46 | await factory.connect(governor).deploy( 47 | arbitrator.address, 48 | arbitratorExtraData, 49 | other.address, // Temporarily set connectedTCR to 'other' account for test purposes. 50 | registrationMetaEvidence, 51 | clearingMetaEvidence, 52 | governor.address, 53 | [submissionBaseDeposit, removalBaseDeposit, submissionChallengeBaseDeposit, removalChallengeBaseDeposit], 54 | challengePeriodDuration, 55 | [sharedStakeMultiplier, winnerStakeMultiplier, loserStakeMultiplier], 56 | relay.address 57 | ); 58 | 59 | const proxyAddress = await factory.instances(0); 60 | gtcr = await ethers.getContractAt("LightGeneralizedTCR", proxyAddress); 61 | }); 62 | it("Should not be possible to initilize a GTCR instance twice.", async () => { 63 | await expectRevert( 64 | gtcr.connect(governor).initialize( 65 | arbitrator.address, 66 | arbitratorExtraData, 67 | other.address, // Temporarily set connectedTCR to 'other' account for test purposes. 68 | registrationMetaEvidence, 69 | clearingMetaEvidence, 70 | governor.address, 71 | [submissionBaseDeposit, removalBaseDeposit, submissionChallengeBaseDeposit, removalChallengeBaseDeposit], 72 | challengePeriodDuration, 73 | [sharedStakeMultiplier, winnerStakeMultiplier, loserStakeMultiplier], 74 | relay.address 75 | ), 76 | "Already initialized." 77 | ); 78 | }); 79 | 80 | it("Should allow multiple deployments.", async () => { 81 | for (let i = 1; i <= 5; i++) { 82 | await factory.connect(governor).deploy( 83 | arbitrator.address, 84 | arbitratorExtraData, 85 | other.address, // Temporarily set connectedTCR to 'other' account for test purposes. 86 | registrationMetaEvidence, 87 | clearingMetaEvidence, 88 | governor.address, 89 | [submissionBaseDeposit, removalBaseDeposit, submissionChallengeBaseDeposit, removalChallengeBaseDeposit], 90 | challengePeriodDuration + i, 91 | [sharedStakeMultiplier, winnerStakeMultiplier, loserStakeMultiplier], 92 | relay.address 93 | ); 94 | const gtcrClone = await ethers.getContractAt("LightGeneralizedTCR", await factory.instances(i)); 95 | expect((await factory.count()).toString()).to.eq((i + 1).toString()); 96 | expect((await gtcrClone.challengePeriodDuration()).toString()).to.eq( 97 | new BN(challengePeriodDuration + i).toString() 98 | ); 99 | } 100 | }); 101 | }); 102 | --------------------------------------------------------------------------------