From 687f8bedcd6da67161f0fca291d57f49ce891cec Mon Sep 17 00:00:00 2001 From: Karol Pietruszka Date: Fri, 15 Apr 2022 11:14:22 +0200 Subject: [PATCH 1/2] create php basic crud using sqlite & php 7.4 --- php-basic-crud/.gitignore | 2 + php-basic-crud/Makefile | 26 + php-basic-crud/README.md | 144 + php-basic-crud/config/bs-config.toml | 10 + php-basic-crud/config/indexer-config.toml | 18 + php-basic-crud/config/logic-config.toml | 23 + php-basic-crud/config/sf-config.toml | 13 + php-basic-crud/config/tm-config.toml | 10 + php-basic-crud/contracts/.dockerignore | 1 + php-basic-crud/contracts/.gitignore | 7 + php-basic-crud/contracts/.prettierrc.json | 3 + php-basic-crud/contracts/Dockerfile | 22 + php-basic-crud/contracts/config/.dapprc.json | 6 + .../config/polygon_mumbai/.dapprc.json | 6 + php-basic-crud/contracts/deploy/01_rollups.ts | 32 + .../deployments/polygon_mumbai/.chainId | 1 + .../polygon_mumbai/ERC20PortalImpl.json | 203 + .../polygon_mumbai/EtherPortalImpl.json | 179 + .../polygon_mumbai/RollupsImpl.json | 659 + .../contracts/export/abi/polygon_mumbai.json | 1735 +++ php-basic-crud/contracts/hardhat.config.ts | 106 + php-basic-crud/contracts/package.json | 92 + php-basic-crud/contracts/tsconfig.json | 12 + php-basic-crud/contracts/yarn.lock | 10371 ++++++++++++++++ php-basic-crud/docker-compose-host.yml | 124 + php-basic-crud/docker-compose.yml | 121 + php-basic-crud/proxy/.gitignore | 3 + php-basic-crud/proxy/Dockerfile | 22 + php-basic-crud/proxy/README.md | 1 + php-basic-crud/proxy/composer.json | 23 + php-basic-crud/proxy/composer.lock | 5676 +++++++++ php-basic-crud/proxy/public/index.php | 67 + php-basic-crud/server/.gitignore | 8 + php-basic-crud/server/Makefile | 73 + php-basic-crud/server/build-dapp-fs.sh | 21 + php-basic-crud/server/build-machine.sh | 24 + php-basic-crud/server/dependencies | 3 + php-basic-crud/server/php/App.php | 96 + php-basic-crud/server/php/Medoo.php | 2233 ++++ php-basic-crud/server/php/Router.php | 535 + php-basic-crud/server/php/Service.php | 29 + .../server/php/controllers/UserController.php | 67 + php-basic-crud/server/php/curl/Request.php | 534 + php-basic-crud/server/php/curl/Response.php | 245 + php-basic-crud/server/php/curl/cURL.php | 379 + .../server/php/curl/cURLException.php | 46 + php-basic-crud/server/php/index.php | 43 + php-basic-crud/server/run-machine-console.sh | 22 + php-basic-crud/server/run.sh | 44 + php-basic-crud/server/shasumfile | 3 + 50 files changed, 24123 insertions(+) create mode 100644 php-basic-crud/.gitignore create mode 100644 php-basic-crud/Makefile create mode 100644 php-basic-crud/README.md create mode 100644 php-basic-crud/config/bs-config.toml create mode 100644 php-basic-crud/config/indexer-config.toml create mode 100644 php-basic-crud/config/logic-config.toml create mode 100644 php-basic-crud/config/sf-config.toml create mode 100644 php-basic-crud/config/tm-config.toml create mode 100644 php-basic-crud/contracts/.dockerignore create mode 100644 php-basic-crud/contracts/.gitignore create mode 100644 php-basic-crud/contracts/.prettierrc.json create mode 100644 php-basic-crud/contracts/Dockerfile create mode 100644 php-basic-crud/contracts/config/.dapprc.json create mode 100644 php-basic-crud/contracts/config/polygon_mumbai/.dapprc.json create mode 100644 php-basic-crud/contracts/deploy/01_rollups.ts create mode 100644 php-basic-crud/contracts/deployments/polygon_mumbai/.chainId create mode 100644 php-basic-crud/contracts/deployments/polygon_mumbai/ERC20PortalImpl.json create mode 100644 php-basic-crud/contracts/deployments/polygon_mumbai/EtherPortalImpl.json create mode 100644 php-basic-crud/contracts/deployments/polygon_mumbai/RollupsImpl.json create mode 100644 php-basic-crud/contracts/export/abi/polygon_mumbai.json create mode 100644 php-basic-crud/contracts/hardhat.config.ts create mode 100644 php-basic-crud/contracts/package.json create mode 100644 php-basic-crud/contracts/tsconfig.json create mode 100644 php-basic-crud/contracts/yarn.lock create mode 100644 php-basic-crud/docker-compose-host.yml create mode 100644 php-basic-crud/docker-compose.yml create mode 100644 php-basic-crud/proxy/.gitignore create mode 100644 php-basic-crud/proxy/Dockerfile create mode 100644 php-basic-crud/proxy/README.md create mode 100644 php-basic-crud/proxy/composer.json create mode 100644 php-basic-crud/proxy/composer.lock create mode 100644 php-basic-crud/proxy/public/index.php create mode 100644 php-basic-crud/server/.gitignore create mode 100644 php-basic-crud/server/Makefile create mode 100755 php-basic-crud/server/build-dapp-fs.sh create mode 100755 php-basic-crud/server/build-machine.sh create mode 100644 php-basic-crud/server/dependencies create mode 100644 php-basic-crud/server/php/App.php create mode 100644 php-basic-crud/server/php/Medoo.php create mode 100644 php-basic-crud/server/php/Router.php create mode 100644 php-basic-crud/server/php/Service.php create mode 100644 php-basic-crud/server/php/controllers/UserController.php create mode 100644 php-basic-crud/server/php/curl/Request.php create mode 100644 php-basic-crud/server/php/curl/Response.php create mode 100644 php-basic-crud/server/php/curl/cURL.php create mode 100644 php-basic-crud/server/php/curl/cURLException.php create mode 100644 php-basic-crud/server/php/index.php create mode 100755 php-basic-crud/server/run-machine-console.sh create mode 100755 php-basic-crud/server/run.sh create mode 100644 php-basic-crud/server/shasumfile diff --git a/php-basic-crud/.gitignore b/php-basic-crud/.gitignore new file mode 100644 index 00000000..b3fa450e --- /dev/null +++ b/php-basic-crud/.gitignore @@ -0,0 +1,2 @@ +machine +**/DS_Store diff --git a/php-basic-crud/Makefile b/php-basic-crud/Makefile new file mode 100644 index 00000000..7638d3c9 --- /dev/null +++ b/php-basic-crud/Makefile @@ -0,0 +1,26 @@ +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +MACHINE_DIR := machine + +.PHONY: clean console + +$(MACHINE_DIR): + @make -C server + @mv server/machine $@ + +console: + @make -C server console + +clean: + @make -C server clean + @rm -rf $(MACHINE_DIR) diff --git a/php-basic-crud/README.md b/php-basic-crud/README.md new file mode 100644 index 00000000..68aafcd4 --- /dev/null +++ b/php-basic-crud/README.md @@ -0,0 +1,144 @@ +# Simple PHP Basic Crud DApp + +This example shows how to build and interact with a minimalistic Cartesi Rollups application. This DApp's back-end is written in PHP. + +## Building the environment + +To run the php-basic-crud example, clone the repository as follows: + +```shell +$ git clone https://github.com/cartesi/rollups-examples.git +``` + +Then, build the back-end for the php-basic-crud example: + +```shell +$ cd rollups-examples/php-basic-crud +$ make machine +``` + +## Running the environment + +In order to start the containers in production mode, simply run: + +```shell +$ docker-compose up --build +``` + +_Note:_ If you decide to use [Docker Compose V2](https://docs.docker.com/compose/cli-command/), make sure you set the [compatibility flag](https://docs.docker.com/compose/cli-command-compatibility/) when executing the command (e.g., `docker compose --compatibility up`). + +Allow some time for the infrastructure to be ready. +How much will depend on your system, but after some time showing the error `"concurrent call in session"`, eventually the container logs will repeatedly show the following: + +```shell +server_manager_1 | Received GetVersion +server_manager_1 | Received GetStatus +server_manager_1 | default_rollups_id +server_manager_1 | Received GetSessionStatus for session default_rollups_id +server_manager_1 | 0 +server_manager_1 | Received GetEpochStatus for session default_rollups_id epoch 0 +``` + +To stop the containers, first end the process with `Ctrl + C`. +Then, remove the containers and associated volumes by executing: + +```shell +$ docker-compose down -v +``` + +## Interacting with the application + +### CLI way + +With the infrastructure in place, go to a separate terminal window and send an input as follows: + +Go to https://www.online-toolz.com/tools/decode-hex.php and paste there following json: + +```json +{ + "path": "/users", + "method": "POST", + "payload": { + "name": "John Doe", + "email": "johndoe@example.com" + } +} +``` + +Copy hex output and replace phrase `` in below command. + +```shell +$ docker exec php-basic-crud-hardhat npx hardhat --network localhost php-basic-crud:addInput --input "0x" +``` + +The input will have been accepted when you receive a response similar to the following one: + +```shell +Added input '0x...' to epoch '0' (timestamp: ..., signer: 0x..., tx: 0x...) +``` + +In order to verify the notices generated by your inputs, run the command: + +```shell +$ curl http://localhost:4000/graphql -H 'Content-Type: application/json' -d '{ "query" : "query getNotice { GetNotice( query: { session_id: \"default_rollups_id\", epoch_index: \"0\", input_index: \"0\" } ) { session_id epoch_index input_index notice_index payload } }" }' +``` + +The response should be something like this: + +```shell +{"data":{"GetNotice":[{"session_id":"default_rollups_id","epoch_index":"0","input_index":"0","notice_index":"0","payload":"63617274657369da"}]}} +``` + +### Built-in PHP proxy server + +You can simply use Postman or even curl and send `POST` request to `http://localhost:8000/users` with payload + +```json +{ + "name": "John Doe", + "email": "johndoe@example.com" +} +``` + +## Advancing time + +To advance time, in order to simulate the passing of epochs, run: + +```shell +$ docker exec echo_hardhat_1 npx hardhat --network localhost util:advanceTime --seconds 864010 +``` + +## Running the environment in host mode + +When developing an application, it is often important to easily test and debug it. For that matter, it is possible to run the Cartesi Rollups environment in [host mode](../README.md#host-mode), so that the DApp's back-end can be executed directly on the host machine, allowing it to be debugged using regular development tools such as an IDE. + +The first step is to run the environment in host mode using the following command: + +```shell +docker-compose -f docker-compose-host.yml up --build +``` +--- + +The next step is to run the PHP server in your machine. The application is written in PHP, so you need to have `php >=7.4` installed. + +In order to start the PHP server, run the following commands in a dedicated terminal: + +Change directory to `php-basic-crud/server` and run `php -S 0.0.0.0:5003 -t php` + +This will run the php-basic-crud server on port `5003` and send the corresponding notices to port `5004`. The server will also automatically reload if there is a change in the source code, enabling fast development iterations. + +The final command, which effectively starts the server, can also be configured in an IDE to allow interactive debugging using features like breakpoints. In that case, it may be interesting to add the parameter `--timeout 0` to gunicorn, to avoid having it time out when the debugger stops at a breakpoint. + +After the server successfully starts, it should print an output like the following: + +``` +[Tue Mar 8 12:08:55 2022] PHP 7.4.27 Development Server (http://0.0.0.0:5003) started +``` + +After that, you can interact with the application normally [as explained above](#interacting-with-the-application). + +Finally, to stop the containers, removing any associated volumes, execute: + +```shell +docker-compose -f docker-compose-host.yml down -v +``` diff --git a/php-basic-crud/config/bs-config.toml b/php-basic-crud/config/bs-config.toml new file mode 100644 index 00000000..2ae813e6 --- /dev/null +++ b/php-basic-crud/config/bs-config.toml @@ -0,0 +1,10 @@ +[block_subscriber] + +# max delay between retries in seconds +max_delay = 64 + +# max number of retries +max_retries = 5 + +# timeout for block subscriber in seconds +timeout = 120 diff --git a/php-basic-crud/config/indexer-config.toml b/php-basic-crud/config/indexer-config.toml new file mode 100644 index 00000000..b9b18b0a --- /dev/null +++ b/php-basic-crud/config/indexer-config.toml @@ -0,0 +1,18 @@ +[polling_config] + +# unique session identifier for machine manager +session_id = "default_rollups_id" + +# node starts syncing from inital epoch +initial_epoch = 0 + +# node starts syncing from epoch index +epoch_index = 0 + +# polling interval +interval = 10 + +# end points +postgres_endpoint = "postgres://postgres:password@database/postgres" +state_server_endpoint = "http://state_server:50051" +mm_endpoint = "http://server_manager:5001" diff --git a/php-basic-crud/config/logic-config.toml b/php-basic-crud/config/logic-config.toml new file mode 100644 index 00000000..46535525 --- /dev/null +++ b/php-basic-crud/config/logic-config.toml @@ -0,0 +1,23 @@ +[logic_config] + +# unique session identifier for machine manager +session_id = "default_rollups_id" + +# node starts syncing from inital epoch +initial_epoch = 0 + +# gas estimation/price multiplier +gas_multiplier = 1 +gas_price_multiplier = 1 + +# number of blocks before resubmting tx +rate = 20 + +# depth of blocks before considering tx finalized +confirmations = 10 + +# end points +provider_http_endpoint = "http://hardhat:8545" +ws_endpoint = "ws://hardhat:8545" +state_fold_grpc_endpoint = "http://state_server:50051" +mm_endpoint = "http://server_manager:5001" diff --git a/php-basic-crud/config/sf-config.toml b/php-basic-crud/config/sf-config.toml new file mode 100644 index 00000000..238fedd3 --- /dev/null +++ b/php-basic-crud/config/sf-config.toml @@ -0,0 +1,13 @@ +[state_fold] + +# concurrent events fetch for state fold access +concurrent_events_fetch = 16 + +# genesis block number for state fold access +genesis_block = "0x1" + +# query limit error for state fold access +query_limit_error_codes = [-32005] + +# number of blocks (depth) before considering state finalized +safety_margin = 1 diff --git a/php-basic-crud/config/tm-config.toml b/php-basic-crud/config/tm-config.toml new file mode 100644 index 00000000..24c5727f --- /dev/null +++ b/php-basic-crud/config/tm-config.toml @@ -0,0 +1,10 @@ +[tx_manager] + +# max delay between retries in seconds +max_delay = 64 + +# max number of retries +max_retries = 5 + +# timeout for a sent transaction in seconds +transaction_timeout = 5 diff --git a/php-basic-crud/contracts/.dockerignore b/php-basic-crud/contracts/.dockerignore new file mode 100644 index 00000000..3c3629e6 --- /dev/null +++ b/php-basic-crud/contracts/.dockerignore @@ -0,0 +1 @@ +node_modules diff --git a/php-basic-crud/contracts/.gitignore b/php-basic-crud/contracts/.gitignore new file mode 100644 index 00000000..76273b68 --- /dev/null +++ b/php-basic-crud/contracts/.gitignore @@ -0,0 +1,7 @@ +cache +coverage +deployments/localhost +deployments/*/solcInputs/*.json +dist +export/abi/localhost.json +node_modules diff --git a/php-basic-crud/contracts/.prettierrc.json b/php-basic-crud/contracts/.prettierrc.json new file mode 100644 index 00000000..0a02bcef --- /dev/null +++ b/php-basic-crud/contracts/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "tabWidth": 4 +} diff --git a/php-basic-crud/contracts/Dockerfile b/php-basic-crud/contracts/Dockerfile new file mode 100644 index 00000000..185790f2 --- /dev/null +++ b/php-basic-crud/contracts/Dockerfile @@ -0,0 +1,22 @@ +FROM node:16-buster-slim + +# install git +RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y \ + git \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# build to bring node_modules +COPY ["package.json", "yarn.lock", "./"] +RUN yarn install --non-interactive + +# build app +COPY . . +RUN yarn install --non-interactive + +# expose hardhat node port +EXPOSE 8545 + +ENTRYPOINT ["npx", "hardhat"] +CMD ["node"] diff --git a/php-basic-crud/contracts/config/.dapprc.json b/php-basic-crud/contracts/config/.dapprc.json new file mode 100644 index 00000000..4cf8cc79 --- /dev/null +++ b/php-basic-crud/contracts/config/.dapprc.json @@ -0,0 +1,6 @@ +{ + "inputDuration": 86400, + "challengePeriod": 604800, + "inputLog2Size": 25, + "validators": "0,1,2" +} diff --git a/php-basic-crud/contracts/config/polygon_mumbai/.dapprc.json b/php-basic-crud/contracts/config/polygon_mumbai/.dapprc.json new file mode 100644 index 00000000..aa2b5133 --- /dev/null +++ b/php-basic-crud/contracts/config/polygon_mumbai/.dapprc.json @@ -0,0 +1,6 @@ +{ + "inputDuration": 86400, + "challengePeriod": 604800, + "inputLog2Size": 25, + "validators": "0" +} diff --git a/php-basic-crud/contracts/deploy/01_rollups.ts b/php-basic-crud/contracts/deploy/01_rollups.ts new file mode 100644 index 00000000..42648b6f --- /dev/null +++ b/php-basic-crud/contracts/deploy/01_rollups.ts @@ -0,0 +1,32 @@ +// Copyright 2022 Cartesi Pte. Ltd. + +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use +// this file except in compliance with the License. You may obtain a copy of the +// License at http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +import { DeployFunction } from "hardhat-deploy/types"; +import { cosmiconfig } from "cosmiconfig"; + +const explorer = cosmiconfig("dapp"); + +const func: DeployFunction = async ({ network, run }) => { + // search for DApp configuration, starting from 'config/{network}' and traversing up + const configResult = await explorer.search(`config/${network.name}`); + + // bail out if we don't find a config + if (!configResult || configResult.isEmpty) { + throw new Error("dapp configuration not found"); + } + + console.log(`dapp configuration loaded from ${configResult.filepath}`); + + // deploy Rollups smart contracts + await run("rollups:create", configResult.config); +}; + +export default func; diff --git a/php-basic-crud/contracts/deployments/polygon_mumbai/.chainId b/php-basic-crud/contracts/deployments/polygon_mumbai/.chainId new file mode 100644 index 00000000..d7e2f72c --- /dev/null +++ b/php-basic-crud/contracts/deployments/polygon_mumbai/.chainId @@ -0,0 +1 @@ +80001 \ No newline at end of file diff --git a/php-basic-crud/contracts/deployments/polygon_mumbai/ERC20PortalImpl.json b/php-basic-crud/contracts/deployments/polygon_mumbai/ERC20PortalImpl.json new file mode 100644 index 00000000..939c95cf --- /dev/null +++ b/php-basic-crud/contracts/deployments/polygon_mumbai/ERC20PortalImpl.json @@ -0,0 +1,203 @@ +{ + "address": "0x485155F7241c851fc7e7F0c58AD43E4FBA5852e2", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_inputContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_outputContract", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "ERC20Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "indexed": false, + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ERC20Withdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "erc20Deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "executeRollupsVoucher", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xb94aa330e7b9d1e1189e42dcfbecb188e1b8c5c1872c56004bb63e9df6e538cd", + "receipt": { + "to": null, + "from": "0x18930e8a66a1DbE21D00581216789AAB7460Afd0", + "contractAddress": "0x485155F7241c851fc7e7F0c58AD43E4FBA5852e2", + "transactionIndex": 14, + "gasUsed": "399962", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100040000000000000000000000000000000000000000000000000000000000000024000100000", + "blockHash": "0x0042bca91e3d296b92b9f2ae726f532e068df003527922479597374116bf3862", + "transactionHash": "0xb94aa330e7b9d1e1189e42dcfbecb188e1b8c5c1872c56004bb63e9df6e538cd", + "logs": [ + { + "transactionIndex": 14, + "blockNumber": 25638502, + "transactionHash": "0xb94aa330e7b9d1e1189e42dcfbecb188e1b8c5c1872c56004bb63e9df6e538cd", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000018930e8a66a1dbe21d00581216789aab7460afd0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000071ad10c3104f80000000000000000000000000000000000000000000000000bae4fc34d5425a7000000000000000000000000000000000000000000000c1a3bbd637866e35b220000000000000000000000000000000000000000000000000ba734f2412320af000000000000000000000000000000000000000000000c1a3bc47e497314601a", + "logIndex": 135, + "blockHash": "0x0042bca91e3d296b92b9f2ae726f532e068df003527922479597374116bf3862" + } + ], + "blockNumber": 25638502, + "cumulativeGasUsed": "3868883", + "status": 1, + "byzantium": true + }, + "args": [ + "0xb5Ccad9FE56FDC70d770b107a6D3B354dDF8D1E6", + "0xB90467e3c4fB5Ac75aAB8D932A4136E5d4EE5814" + ], + "numDeployments": 2, + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_inputContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_outputContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ERC20\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ERC20Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ERC20\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"ERC20Withdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ERC20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"erc20Deposit\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeRollupsVoucher\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"erc20Deposit(address,uint256,bytes)\":{\"params\":{\"_ERC20\":\"address of the ERC20 token contract\",\"_amount\":\"amount of the ERC20 token to be deposited\",\"_data\":\"information to be interpreted by L2\"},\"returns\":{\"_0\":\"hash of input generated by deposit\"}},\"executeRollupsVoucher(bytes)\":{\"details\":\"can only be called by the Output contract\",\"params\":{\"_data\":\"data with information necessary to execute voucher\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"erc20Deposit(address,uint256,bytes)\":{\"notice\":\"deposit an amount of a generic ERC20 in the portal contract and create tokens in L2\"},\"executeRollupsVoucher(bytes)\":{\"notice\":\"execute a rollups voucher\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ERC20PortalImpl.sol\":\"ERC20PortalImpl\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"contracts/ERC20Portal.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Generic ERC20 Portal\\npragma solidity >=0.7.0;\\n\\ninterface ERC20Portal {\\n /// @notice deposit an amount of a generic ERC20 in the portal contract and create tokens in L2\\n /// @param _ERC20 address of the ERC20 token contract\\n /// @param _amount amount of the ERC20 token to be deposited\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function erc20Deposit(\\n address _ERC20,\\n uint256 _amount,\\n bytes calldata _data\\n ) external returns (bytes32);\\n\\n /// @notice execute a rollups voucher\\n /// @param _data data with information necessary to execute voucher\\n /// @dev can only be called by the Output contract\\n function executeRollupsVoucher(bytes calldata _data)\\n external\\n returns (bool);\\n\\n // @notice emitted on ERC20 deposited\\n event ERC20Deposited(\\n address _ERC20,\\n address _sender,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n // @notice emitted on ERC20 withdrawal\\n event ERC20Withdrawn(\\n address _ERC20,\\n address payable _receiver,\\n uint256 _amount\\n );\\n}\\n\",\"keccak256\":\"0x85e430776d98bafff97a8c58dddce18f329247251f5706c792fdcba0db2cf009\",\"license\":\"Apache-2.0\"},\"contracts/ERC20PortalImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Generic ERC20 Portal Implementation\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport \\\"./ERC20Portal.sol\\\";\\nimport \\\"./Input.sol\\\";\\n\\ncontract ERC20PortalImpl is ERC20Portal {\\n address immutable outputContract;\\n Input immutable inputContract;\\n\\n modifier onlyOutputContract {\\n require(msg.sender == outputContract, \\\"only outputContract\\\");\\n _;\\n }\\n\\n constructor(address _inputContract, address _outputContract) {\\n inputContract = Input(_inputContract);\\n outputContract = _outputContract;\\n }\\n\\n /// @notice deposit an amount of a generic ERC20 in the portal contract and create tokens in L2\\n /// @param _ERC20 address of the ERC20 token contract\\n /// @param _amount amount of the ERC20 token to be deposited\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function erc20Deposit(\\n address _ERC20,\\n uint256 _amount,\\n bytes calldata _data\\n ) public override returns (bytes32) {\\n IERC20 token = IERC20(_ERC20);\\n\\n require(\\n token.transferFrom(msg.sender, address(this), _amount),\\n \\\"ERC20 transferFrom failed\\\"\\n );\\n\\n bytes memory input =\\n abi.encode(\\n msg.sender,\\n _ERC20,\\n _amount,\\n _data\\n );\\n\\n emit ERC20Deposited(_ERC20, msg.sender, _amount, _data);\\n return inputContract.addInput(input);\\n }\\n\\n /// @notice execute a rollups voucher\\n /// @param _data data with information necessary to execute voucher\\n /// @dev can only be called by the Output contract\\n function executeRollupsVoucher(bytes calldata _data)\\n public\\n override\\n onlyOutputContract\\n returns (bool)\\n {\\n (\\n address tokenAddr,\\n address payable receiver,\\n uint256 value\\n ) = abi.decode(_data, (address, address, uint256));\\n\\n IERC20 token = IERC20(tokenAddr);\\n\\n // transfer reverts on failure\\n token.transfer(receiver, value);\\n\\n emit ERC20Withdrawn(tokenAddr, receiver, value);\\n\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe1d1cc22e7123850a320b8cebe5d0e5ff114137b46e722843a4dd9b4ff433dab\",\"license\":\"Apache-2.0\"},\"contracts/Input.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input\\npragma solidity >=0.7.0;\\n\\ninterface Input {\\n /// @notice adds input to correct inbox\\n /// @param _input bytes array of input\\n /// @return merkle root hash of input\\n /// @dev msg.sender and timestamp are preppended log2 size\\n /// has to be calculated offchain taking that into account\\n function addInput(bytes calldata _input) external returns (bytes32);\\n\\n /// @notice returns input from correct input inbox\\n /// @param _index position of the input on inbox\\n /// @return root hash of input\\n function getInput(uint256 _index) external view returns (bytes32);\\n\\n /// @notice returns number of inputs on correct inbox\\n /// @return number of inputs of non active inbox\\n function getNumberOfInputs() external view returns (uint256);\\n\\n /// @notice returns active current inbox index\\n /// @return index of current active inbox\\n function getCurrentInbox() external view returns (uint256);\\n\\n /// @notice called whenever there is a new input accumulation epoch\\n /// @dev has to be called even if new input accumulation happens\\n /// implicitly due to a new epoch\\n function onNewInputAccumulation() external;\\n\\n /// @notice called when a new epoch begins, clears correct input box\\n function onNewEpoch() external;\\n\\n /// @notice input added\\n /// @param _epochNumber which epoch this input belongs to\\n /// @param _inputIndex index of the input just added\\n /// @param _sender msg.sender\\n /// @param _timestamp block.timestamp\\n /// @param _input input data\\n event InputAdded(\\n uint256 indexed _epochNumber,\\n uint256 indexed _inputIndex,\\n address _sender,\\n uint256 _timestamp,\\n bytes _input\\n );\\n}\\n\",\"keccak256\":\"0x77b327595fd5b8a5d16f4cb42187068288c82d21f17581117d07f449d7b75939\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b506040516106f33803806106f383398101604081905261002f91610062565b6001600160a01b0391821660a05216608052610095565b80516001600160a01b038116811461005d57600080fd5b919050565b6000806040838503121561007557600080fd5b61007e83610046565b915061008c60208401610046565b90509250929050565b60805160a05161063a6100b96000396000610347015260006091015261063a6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635a78177d1461003b578063cb1061a614610063575b600080fd5b61004e610049366004610422565b610084565b60405190151581526020015b60405180910390f35b61007661007136600461047c565b6101ee565b60405190815260200161005a565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100f95760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e481bdd5d1c1d5d10dbdb9d1c9858dd606a1b60448201526064015b60405180910390fd5b60008080610109858701876104d8565b60405163a9059cbb60e01b81526001600160a01b038084166004830152602482018390529396509194509250849182169063a9059cbb90604401602060405180830381600087803b15801561015d57600080fd5b505af1158015610171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101959190610519565b50604080516001600160a01b038087168252851660208201529081018390527fbfed55bdcd242e3dd0f60ddd7d1e87c67f61c34cd9527b3e6455d841b10253629060600160405180910390a15060019695505050505050565b6040516323b872dd60e01b81523360048201523060248201526044810184905260009085906001600160a01b038216906323b872dd90606401602060405180830381600087803b15801561024157600080fd5b505af1158015610255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102799190610519565b6102c55760405162461bcd60e51b815260206004820152601960248201527f4552433230207472616e7366657246726f6d206661696c65640000000000000060448201526064016100f0565b600033878787876040516020016102e0959493929190610542565b60405160208183030381529060405290507f29e6a9ed1b00933e0de5679ea9bc6ad323969a70b69b627425b46ac0431c7b018733888888604051610328959493929190610542565b60405180910390a1604051631e640f1d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f32078e89061037c908490600401610596565b602060405180830381600087803b15801561039657600080fd5b505af11580156103aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ce91906105eb565b979650505050505050565b60008083601f8401126103eb57600080fd5b50813567ffffffffffffffff81111561040357600080fd5b60208301915083602082850101111561041b57600080fd5b9250929050565b6000806020838503121561043557600080fd5b823567ffffffffffffffff81111561044c57600080fd5b610458858286016103d9565b90969095509350505050565b6001600160a01b038116811461047957600080fd5b50565b6000806000806060858703121561049257600080fd5b843561049d81610464565b935060208501359250604085013567ffffffffffffffff8111156104c057600080fd5b6104cc878288016103d9565b95989497509550505050565b6000806000606084860312156104ed57600080fd5b83356104f881610464565b9250602084013561050881610464565b929592945050506040919091013590565b60006020828403121561052b57600080fd5b8151801515811461053b57600080fd5b9392505050565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b600060208083528351808285015260005b818110156105c3578581018301518582016040015282016105a7565b818111156105d5576000604083870101525b50601f01601f1916929092016040019392505050565b6000602082840312156105fd57600080fd5b505191905056fea2646970667358221220fd1649f0899420b65f77b06fe8f7f1aa15f38ec7ece302e769cba19d012754dd64736f6c63430008090033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80635a78177d1461003b578063cb1061a614610063575b600080fd5b61004e610049366004610422565b610084565b60405190151581526020015b60405180910390f35b61007661007136600461047c565b6101ee565b60405190815260200161005a565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100f95760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e481bdd5d1c1d5d10dbdb9d1c9858dd606a1b60448201526064015b60405180910390fd5b60008080610109858701876104d8565b60405163a9059cbb60e01b81526001600160a01b038084166004830152602482018390529396509194509250849182169063a9059cbb90604401602060405180830381600087803b15801561015d57600080fd5b505af1158015610171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101959190610519565b50604080516001600160a01b038087168252851660208201529081018390527fbfed55bdcd242e3dd0f60ddd7d1e87c67f61c34cd9527b3e6455d841b10253629060600160405180910390a15060019695505050505050565b6040516323b872dd60e01b81523360048201523060248201526044810184905260009085906001600160a01b038216906323b872dd90606401602060405180830381600087803b15801561024157600080fd5b505af1158015610255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102799190610519565b6102c55760405162461bcd60e51b815260206004820152601960248201527f4552433230207472616e7366657246726f6d206661696c65640000000000000060448201526064016100f0565b600033878787876040516020016102e0959493929190610542565b60405160208183030381529060405290507f29e6a9ed1b00933e0de5679ea9bc6ad323969a70b69b627425b46ac0431c7b018733888888604051610328959493929190610542565b60405180910390a1604051631e640f1d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f32078e89061037c908490600401610596565b602060405180830381600087803b15801561039657600080fd5b505af11580156103aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ce91906105eb565b979650505050505050565b60008083601f8401126103eb57600080fd5b50813567ffffffffffffffff81111561040357600080fd5b60208301915083602082850101111561041b57600080fd5b9250929050565b6000806020838503121561043557600080fd5b823567ffffffffffffffff81111561044c57600080fd5b610458858286016103d9565b90969095509350505050565b6001600160a01b038116811461047957600080fd5b50565b6000806000806060858703121561049257600080fd5b843561049d81610464565b935060208501359250604085013567ffffffffffffffff8111156104c057600080fd5b6104cc878288016103d9565b95989497509550505050565b6000806000606084860312156104ed57600080fd5b83356104f881610464565b9250602084013561050881610464565b929592945050506040919091013590565b60006020828403121561052b57600080fd5b8151801515811461053b57600080fd5b9392505050565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b600060208083528351808285015260005b818110156105c3578581018301518582016040015282016105a7565b818111156105d5576000604083870101525b50601f01601f1916929092016040019392505050565b6000602082840312156105fd57600080fd5b505191905056fea2646970667358221220fd1649f0899420b65f77b06fe8f7f1aa15f38ec7ece302e769cba19d012754dd64736f6c63430008090033", + "devdoc": { + "kind": "dev", + "methods": { + "erc20Deposit(address,uint256,bytes)": { + "params": { + "_ERC20": "address of the ERC20 token contract", + "_amount": "amount of the ERC20 token to be deposited", + "_data": "information to be interpreted by L2" + }, + "returns": { + "_0": "hash of input generated by deposit" + } + }, + "executeRollupsVoucher(bytes)": { + "details": "can only be called by the Output contract", + "params": { + "_data": "data with information necessary to execute voucher" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "erc20Deposit(address,uint256,bytes)": { + "notice": "deposit an amount of a generic ERC20 in the portal contract and create tokens in L2" + }, + "executeRollupsVoucher(bytes)": { + "notice": "execute a rollups voucher" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/php-basic-crud/contracts/deployments/polygon_mumbai/EtherPortalImpl.json b/php-basic-crud/contracts/deployments/polygon_mumbai/EtherPortalImpl.json new file mode 100644 index 00000000..5c226032 --- /dev/null +++ b/php-basic-crud/contracts/deployments/polygon_mumbai/EtherPortalImpl.json @@ -0,0 +1,179 @@ +{ + "address": "0x794E1A83C525ecF06Cd7f33297368A3dbf3e7e8A", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_inputContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_outputContract", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "EtherDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "EtherWithdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "etherDeposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "executeRollupsVoucher", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x914db613a2c60153ca4110d1b95a80e1486acb93ec219c54d053f59c9c8f9aa9", + "receipt": { + "to": null, + "from": "0x18930e8a66a1DbE21D00581216789AAB7460Afd0", + "contractAddress": "0x794E1A83C525ecF06Cd7f33297368A3dbf3e7e8A", + "transactionIndex": 8, + "gasUsed": "308794", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100040000000000000000000000000000000000000000000000000000000000000024000100000", + "blockHash": "0x213bf8fa01956330d7a6ff863fb82d281a4ebdd13ae7eb1c79ad53d94f5b195b", + "transactionHash": "0x914db613a2c60153ca4110d1b95a80e1486acb93ec219c54d053f59c9c8f9aa9", + "logs": [ + { + "transactionIndex": 8, + "blockNumber": 25638501, + "transactionHash": "0x914db613a2c60153ca4110d1b95a80e1486acb93ec219c54d053f59c9c8f9aa9", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000018930e8a66a1dbe21d00581216789aab7460afd0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x0000000000000000000000000000000000000000000000000015f0ee1d3513780000000000000000000000000000000000000000000000000bc440b16ae775a7000000000000000000000000000000000000000000000c1a39747f85e3d556e40000000000000000000000000000000000000000000000000bae4fc34db2622f000000000000000000000000000000000000000000000c1a398a7074010a6a5c", + "logIndex": 119, + "blockHash": "0x213bf8fa01956330d7a6ff863fb82d281a4ebdd13ae7eb1c79ad53d94f5b195b" + } + ], + "blockNumber": 25638501, + "cumulativeGasUsed": "2992944", + "status": 1, + "byzantium": true + }, + "args": [ + "0xb5Ccad9FE56FDC70d770b107a6D3B354dDF8D1E6", + "0xB90467e3c4fB5Ac75aAB8D932A4136E5d4EE5814" + ], + "numDeployments": 2, + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_inputContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_outputContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"EtherDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"EtherWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"etherDeposit\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeRollupsVoucher\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"etherDeposit(bytes)\":{\"params\":{\"_data\":\"information to be interpreted by L2\"},\"returns\":{\"_0\":\"hash of input generated by deposit\"}},\"executeRollupsVoucher(bytes)\":{\"details\":\"can only be called by the Output contract\",\"params\":{\"_data\":\"data with information necessary to execute voucher\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"etherDeposit(bytes)\":{\"notice\":\"deposit an amount of Ether in the portal contract and create Ether in L2\"},\"executeRollupsVoucher(bytes)\":{\"notice\":\"executes a rollups voucher\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/EtherPortalImpl.sol\":\"EtherPortalImpl\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/EtherPortal.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Ether Portal\\npragma solidity >=0.7.0;\\n\\ninterface EtherPortal {\\n /// @notice deposit an amount of Ether in the portal contract and create Ether in L2\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function etherDeposit(\\n bytes calldata _data\\n ) external payable returns (bytes32);\\n\\n /// @notice execute a rollups voucher\\n /// @param _data data with information necessary to execute voucher\\n /// @dev can only be called by the Output contract\\n function executeRollupsVoucher(bytes calldata _data)\\n external\\n returns (bool);\\n\\n // @notice emitted on Ether deposited\\n event EtherDeposited(\\n address _sender,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n // @notice emitted on Ether withdrawal\\n event EtherWithdrawn(\\n address payable _receiver,\\n uint256 _amount\\n );\\n}\\n\",\"keccak256\":\"0xb284f9d2b2707df4671c019ed4fc0e3173d713c19ee1055f670a88767197c85e\",\"license\":\"Apache-2.0\"},\"contracts/EtherPortalImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Ether Portal Implementation\\npragma solidity ^0.8.0;\\n\\nimport \\\"./EtherPortal.sol\\\";\\nimport \\\"./Input.sol\\\";\\n\\ncontract EtherPortalImpl is EtherPortal {\\n address immutable outputContract;\\n Input immutable inputContract;\\n\\n modifier onlyOutputContract {\\n require(msg.sender == outputContract, \\\"only outputContract\\\");\\n _;\\n }\\n\\n constructor(address _inputContract, address _outputContract) {\\n inputContract = Input(_inputContract);\\n outputContract = _outputContract;\\n }\\n\\n /// @notice deposit an amount of Ether in the portal contract and create Ether in L2\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function etherDeposit(\\n bytes calldata _data\\n ) public payable override returns (bytes32) {\\n bytes memory input =\\n abi.encode(msg.sender, msg.value, _data);\\n\\n emit EtherDeposited(msg.sender, msg.value, _data);\\n return inputContract.addInput(input);\\n }\\n\\n /// @notice executes a rollups voucher\\n /// @param _data data with information necessary to execute voucher\\n /// @dev can only be called by the Output contract\\n function executeRollupsVoucher(bytes calldata _data)\\n public\\n override\\n onlyOutputContract\\n returns (bool)\\n {\\n (\\n address payable receiver,\\n uint256 value\\n ) = abi.decode(_data, (address, uint256));\\n\\n // We used to call receiver.transfer(value) but it's no\\n // longer considered safe, as it assumes gas costs are\\n // immutable, while in fact they are not.\\n (bool success, ) = receiver.call{value: value}(\\\"\\\");\\n require(success, \\\"transfer failed\\\");\\n\\n emit EtherWithdrawn(receiver, value);\\n\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x2830efd3857cfe12080ec5bdb55e6c14a800f986b3dd38d155f15b67ea550d6d\",\"license\":\"Apache-2.0\"},\"contracts/Input.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input\\npragma solidity >=0.7.0;\\n\\ninterface Input {\\n /// @notice adds input to correct inbox\\n /// @param _input bytes array of input\\n /// @return merkle root hash of input\\n /// @dev msg.sender and timestamp are preppended log2 size\\n /// has to be calculated offchain taking that into account\\n function addInput(bytes calldata _input) external returns (bytes32);\\n\\n /// @notice returns input from correct input inbox\\n /// @param _index position of the input on inbox\\n /// @return root hash of input\\n function getInput(uint256 _index) external view returns (bytes32);\\n\\n /// @notice returns number of inputs on correct inbox\\n /// @return number of inputs of non active inbox\\n function getNumberOfInputs() external view returns (uint256);\\n\\n /// @notice returns active current inbox index\\n /// @return index of current active inbox\\n function getCurrentInbox() external view returns (uint256);\\n\\n /// @notice called whenever there is a new input accumulation epoch\\n /// @dev has to be called even if new input accumulation happens\\n /// implicitly due to a new epoch\\n function onNewInputAccumulation() external;\\n\\n /// @notice called when a new epoch begins, clears correct input box\\n function onNewEpoch() external;\\n\\n /// @notice input added\\n /// @param _epochNumber which epoch this input belongs to\\n /// @param _inputIndex index of the input just added\\n /// @param _sender msg.sender\\n /// @param _timestamp block.timestamp\\n /// @param _input input data\\n event InputAdded(\\n uint256 indexed _epochNumber,\\n uint256 indexed _inputIndex,\\n address _sender,\\n uint256 _timestamp,\\n bytes _input\\n );\\n}\\n\",\"keccak256\":\"0x77b327595fd5b8a5d16f4cb42187068288c82d21f17581117d07f449d7b75939\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b5060405161054d38038061054d83398101604081905261002f91610062565b6001600160a01b0391821660a05216608052610095565b80516001600160a01b038116811461005d57600080fd5b919050565b6000806040838503121561007557600080fd5b61007e83610046565b915061008c60208401610046565b90509250929050565b60805160a0516104936100ba60003960006101030152600061019f01526104936000f3fe6080604052600436106100295760003560e01c80632abfe7b31461002e5780635a78177d14610054575b600080fd5b61004161003c3660046102fd565b610084565b6040519081526020015b60405180910390f35b34801561006057600080fd5b5061007461006f3660046102fd565b610192565b604051901515815260200161004b565b6000803334858560405160200161009e949392919061036f565b60405160208183030381529060405290507fa9888e32d8ea552aaeb3018b9c85c77c66ecc61cf8d1989f9e3271a88205ee63333486866040516100e4949392919061036f565b60405180910390a1604051631e640f1d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f32078e8906101389084906004016103b7565b602060405180830381600087803b15801561015257600080fd5b505af1158015610166573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018a919061040c565b949350505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102075760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e481bdd5d1c1d5d10dbdb9d1c9858dd606a1b60448201526064015b60405180910390fd5b60008061021684860186610425565b915091506000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610267576040519150601f19603f3d011682016040523d82523d6000602084013e61026c565b606091505b50509050806102af5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064016101fe565b604080516001600160a01b0385168152602081018490527f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c910160405180910390a150600195945050505050565b6000806020838503121561031057600080fd5b823567ffffffffffffffff8082111561032857600080fd5b818501915085601f83011261033c57600080fd5b81358181111561034b57600080fd5b86602082850101111561035d57600080fd5b60209290920196919550909350505050565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600060208083528351808285015260005b818110156103e4578581018301518582016040015282016103c8565b818111156103f6576000604083870101525b50601f01601f1916929092016040019392505050565b60006020828403121561041e57600080fd5b5051919050565b6000806040838503121561043857600080fd5b82356001600160a01b038116811461044f57600080fd5b94602093909301359350505056fea26469706673582212207fe9038a97b0ffdd6ca5910a4c2cde000e15c9c698cd3eaa3fe60ed29cf6f65164736f6c63430008090033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80632abfe7b31461002e5780635a78177d14610054575b600080fd5b61004161003c3660046102fd565b610084565b6040519081526020015b60405180910390f35b34801561006057600080fd5b5061007461006f3660046102fd565b610192565b604051901515815260200161004b565b6000803334858560405160200161009e949392919061036f565b60405160208183030381529060405290507fa9888e32d8ea552aaeb3018b9c85c77c66ecc61cf8d1989f9e3271a88205ee63333486866040516100e4949392919061036f565b60405180910390a1604051631e640f1d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f32078e8906101389084906004016103b7565b602060405180830381600087803b15801561015257600080fd5b505af1158015610166573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018a919061040c565b949350505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102075760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e481bdd5d1c1d5d10dbdb9d1c9858dd606a1b60448201526064015b60405180910390fd5b60008061021684860186610425565b915091506000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610267576040519150601f19603f3d011682016040523d82523d6000602084013e61026c565b606091505b50509050806102af5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064016101fe565b604080516001600160a01b0385168152602081018490527f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c910160405180910390a150600195945050505050565b6000806020838503121561031057600080fd5b823567ffffffffffffffff8082111561032857600080fd5b818501915085601f83011261033c57600080fd5b81358181111561034b57600080fd5b86602082850101111561035d57600080fd5b60209290920196919550909350505050565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600060208083528351808285015260005b818110156103e4578581018301518582016040015282016103c8565b818111156103f6576000604083870101525b50601f01601f1916929092016040019392505050565b60006020828403121561041e57600080fd5b5051919050565b6000806040838503121561043857600080fd5b82356001600160a01b038116811461044f57600080fd5b94602093909301359350505056fea26469706673582212207fe9038a97b0ffdd6ca5910a4c2cde000e15c9c698cd3eaa3fe60ed29cf6f65164736f6c63430008090033", + "devdoc": { + "kind": "dev", + "methods": { + "etherDeposit(bytes)": { + "params": { + "_data": "information to be interpreted by L2" + }, + "returns": { + "_0": "hash of input generated by deposit" + } + }, + "executeRollupsVoucher(bytes)": { + "details": "can only be called by the Output contract", + "params": { + "_data": "data with information necessary to execute voucher" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "etherDeposit(bytes)": { + "notice": "deposit an amount of Ether in the portal contract and create Ether in L2" + }, + "executeRollupsVoucher(bytes)": { + "notice": "executes a rollups voucher" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/php-basic-crud/contracts/deployments/polygon_mumbai/RollupsImpl.json b/php-basic-crud/contracts/deployments/polygon_mumbai/RollupsImpl.json new file mode 100644 index 00000000..1dc14499 --- /dev/null +++ b/php-basic-crud/contracts/deployments/polygon_mumbai/RollupsImpl.json @@ -0,0 +1,659 @@ +{ + "address": "0x2DE3edbcF55a1FAC46c665Bb8C0Fd95FB353deEa", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_inputDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_challengePeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_inputLog2Size", + "type": "uint256" + }, + { + "internalType": "address payable[]", + "name": "_validators", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_claimer", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "FinalizeEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Rollups.Phase", + "name": "_newPhase", + "type": "uint8" + } + ], + "name": "PhaseChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_winner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_loser", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_winningClaim", + "type": "bytes32" + } + ], + "name": "ResolveDispute", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_input", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_output", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_validatorManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_disputeManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_inputDuration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_challengePeriod", + "type": "uint256" + } + ], + "name": "RollupsCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disputeManager", + "outputs": [ + { + "internalType": "contract DisputeManagerImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "finalizeEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentPhase", + "outputs": [ + { + "internalType": "enum Rollups.Phase", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDisputeManagerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputAccumulationStart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOutputAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorManagerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "input", + "outputs": [ + { + "internalType": "contract InputImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "notifyInput", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "output", + "outputs": [ + { + "internalType": "contract OutputImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_winner", + "type": "address" + }, + { + "internalType": "address payable", + "name": "_loser", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_winningClaim", + "type": "bytes32" + } + ], + "name": "resolveDispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "storageVar", + "outputs": [ + { + "internalType": "uint32", + "name": "inputDuration", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "challengePeriod", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "inputAccumulationStart", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "sealingEpochTimestamp", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "currentPhase_int", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validatorManager", + "outputs": [ + { + "internalType": "contract ValidatorManagerImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xb389959e2d23a0711afc3103234b0267ace7c8a857081e2d841df755d649d792", + "receipt": { + "to": null, + "from": "0x18930e8a66a1DbE21D00581216789AAB7460Afd0", + "contractAddress": "0x2DE3edbcF55a1FAC46c665Bb8C0Fd95FB353deEa", + "transactionIndex": 2, + "gasUsed": "3154082", + "logsBloom": "0x0000000001000000000000020000000000000000000000000000002000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000080000000000000000000010000000000400000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000008000000000000000000020040000000000000000000000000000000000000000000400000000000000400000000000000000000100000000000000000000000000000010004000000000000000000000000000000000200000000000000000000000000002c000100000", + "blockHash": "0x4219b1989842285f699875f79dfdbc19501fd898f784944cae71c7d469f9e522", + "transactionHash": "0xb389959e2d23a0711afc3103234b0267ace7c8a857081e2d841df755d649d792", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 25638500, + "transactionHash": "0xb389959e2d23a0711afc3103234b0267ace7c8a857081e2d841df755d649d792", + "address": "0x2DE3edbcF55a1FAC46c665Bb8C0Fd95FB353deEa", + "topics": [ + "0x0c34d7ca767e7f7b827de620cbd78c6291e2ca28d8ac112f26c5121912ea1ecc" + ], + "data": "0x000000000000000000000000b5ccad9fe56fdc70d770b107a6d3b354ddf8d1e6000000000000000000000000b90467e3c4fb5ac75aab8d932a4136e5d4ee58140000000000000000000000002eec2d8242b05e9dfbad0b0a0e62b39966b1dc280000000000000000000000005fc9fb6cd7320817e70a64eace9f5c5f960f39fa00000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000093a80", + "logIndex": 104, + "blockHash": "0x4219b1989842285f699875f79dfdbc19501fd898f784944cae71c7d469f9e522" + }, + { + "transactionIndex": 2, + "blockNumber": 25638500, + "transactionHash": "0xb389959e2d23a0711afc3103234b0267ace7c8a857081e2d841df755d649d792", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000018930e8a66a1dbe21d00581216789aab7460afd0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000e01c6ad44a03580000000000000000000000000000000000000000000000000ca45d1c42f405a7000000000000000000000000000000000000000000000c1a364c90d1e5d062e10000000000000000000000000000000000000000000000000bc440b16eaa024f000000000000000000000000000000000000000000000c1a372cad3cba1a6639", + "logIndex": 105, + "blockHash": "0x4219b1989842285f699875f79dfdbc19501fd898f784944cae71c7d469f9e522" + } + ], + "blockNumber": 25638500, + "cumulativeGasUsed": "4519620", + "status": 1, + "byzantium": true + }, + "args": [ + 86400, + 604800, + 25, + [ + "0x18930e8a66a1DbE21D00581216789AAB7460Afd0" + ] + ], + "numDeployments": 2, + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inputDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_challengePeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_inputLog2Size\",\"type\":\"uint256\"},{\"internalType\":\"address payable[]\",\"name\":\"_validators\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_epochNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_claimer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_epochHash\",\"type\":\"bytes32\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_epochNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_epochHash\",\"type\":\"bytes32\"}],\"name\":\"FinalizeEpoch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Rollups.Phase\",\"name\":\"_newPhase\",\"type\":\"uint8\"}],\"name\":\"PhaseChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_loser\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_winningClaim\",\"type\":\"bytes32\"}],\"name\":\"ResolveDispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_input\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_output\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_validatorManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inputDuration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_challengePeriod\",\"type\":\"uint256\"}],\"name\":\"RollupsCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_epochHash\",\"type\":\"bytes32\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disputeManager\",\"outputs\":[{\"internalType\":\"contract DisputeManagerImpl\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalizeEpoch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentPhase\",\"outputs\":[{\"internalType\":\"enum Rollups.Phase\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDisputeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputAccumulationStart\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOutputAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getValidatorManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"input\",\"outputs\":[{\"internalType\":\"contract InputImpl\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notifyInput\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"output\",\"outputs\":[{\"internalType\":\"contract OutputImpl\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_winner\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_loser\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_winningClaim\",\"type\":\"bytes32\"}],\"name\":\"resolveDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"storageVar\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"inputDuration\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"challengePeriod\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"inputAccumulationStart\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"sealingEpochTimestamp\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"currentPhase_int\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorManager\",\"outputs\":[{\"internalType\":\"contract ValidatorManagerImpl\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_challengePeriod\":\"duration of challenge period in seconds\",\"_inputDuration\":\"duration of input accumulation phase in seconds\",\"_inputLog2Size\":\"size of the input drive in this machine\",\"_validators\":\"initial validator set\"}},\"finalizeEpoch()\":{\"details\":\"can only be called if challenge period is over\"},\"getCurrentEpoch()\":{\"details\":\"if phase is input accumulation, then the epoch number is length\",\"returns\":{\"_0\":\"index of current epoch\"}},\"notifyInput()\":{\"details\":\"can only be called by input contract\"},\"resolveDispute(address,address,bytes32)\":{\"details\":\"can only be called by the dispute contract\",\"params\":{\"_loser\":\"loser of dispute\",\"_winner\":\"winner of dispute\",\"_winningClaim\":\"initial claim of winning validator\"}}},\"version\":1},\"userdoc\":{\"events\":{\"Claim(uint256,address,bytes32)\":{\"notice\":\"claim submitted\"},\"FinalizeEpoch(uint256,bytes32)\":{\"notice\":\"epoch finalized\"},\"PhaseChange(uint8)\":{\"notice\":\"phase change\"},\"ResolveDispute(address,address,bytes32)\":{\"notice\":\"dispute resolved\"},\"RollupsCreated(address,address,address,address,uint256,uint256)\":{\"notice\":\"contract created\"}},\"kind\":\"user\",\"methods\":{\"claim(bytes32)\":{\"notice\":\"TODO: add signatures for aggregated claims\"},\"constructor\":{\"notice\":\"creates contract\"},\"finalizeEpoch()\":{\"notice\":\"finalize epoch after timeout\"},\"getCurrentEpoch()\":{\"notice\":\"returns index of current (accumulating) epoch\"},\"getCurrentPhase()\":{\"notice\":\"returns the current phase\"},\"getDisputeManagerAddress()\":{\"notice\":\"returns address of dispute manager contract\"},\"getInputAccumulationStart()\":{\"notice\":\"returns the input accumulation start timestamp\"},\"getInputAddress()\":{\"notice\":\"returns address of input contract\"},\"getOutputAddress()\":{\"notice\":\"returns address of output contract\"},\"getValidatorManagerAddress()\":{\"notice\":\"returns address of validator manager contract\"},\"notifyInput()\":{\"notice\":\"called when new input arrives, manages the phase changes\"},\"resolveDispute(address,address,bytes32)\":{\"notice\":\"called when a dispute is resolved by the dispute manager\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RollupsImpl.sol\":\"RollupsImpl\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@cartesi/util/contracts/Bitmask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\npragma solidity ^0.8.0;\\n\\n/// @title Bit Mask Library\\n/// @author Stephen Chen\\n/// @notice Implements bit mask with dynamic array\\nlibrary Bitmask {\\n /// @notice Set a bit in the bit mask\\n function setBit(\\n mapping(uint256 => uint256) storage bitmask,\\n uint256 _bit,\\n bool _value\\n ) public {\\n // calculate the number of bits has been store in bitmask now\\n uint256 positionOfMask = uint256(_bit / 256);\\n uint256 positionOfBit = _bit % 256;\\n\\n if (_value) {\\n bitmask[positionOfMask] =\\n bitmask[positionOfMask] |\\n (1 << positionOfBit);\\n } else {\\n bitmask[positionOfMask] =\\n bitmask[positionOfMask] &\\n ~(1 << positionOfBit);\\n }\\n }\\n\\n /// @notice Get a bit in the bit mask\\n function getBit(mapping(uint256 => uint256) storage bitmask, uint256 _bit)\\n public\\n view\\n returns (bool)\\n {\\n // calculate the number of bits has been store in bitmask now\\n uint256 positionOfMask = uint256(_bit / 256);\\n uint256 positionOfBit = _bit % 256;\\n\\n return ((bitmask[positionOfMask] & (1 << positionOfBit)) != 0);\\n }\\n}\\n\",\"keccak256\":\"0xe35cf68672f5844589c0e56f36aa3813ca4ffb882a55a46d15adac7e3cc889bd\",\"license\":\"Apache-2.0\"},\"@cartesi/util/contracts/CartesiMath.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title CartesiMath\\n/// @author Felipe Argento\\npragma solidity ^0.8.0;\\n\\nlibrary CartesiMath {\\n // mapping values are packed as bytes3 each\\n // see test/TestCartesiMath.ts for decimal values\\n bytes constant log2tableTimes1M =\\n hex\\\"0000000F4240182F421E8480236E082771822AD63A2DC6C0305E8532B04834C96736B3C23876D73A187A3B9D4A3D09003E5EA63FA0C540D17741F28843057D440BA745062945F60246DC1047B917488DC7495ABA4A207C4ADF8A4B98544C4B404CF8AA4DA0E64E44434EE3054F7D6D5013B750A61A5134C851BFF05247BD52CC58534DE753CC8D54486954C19C55384255AC75561E50568DE956FB575766B057D00758376F589CFA5900BA5962BC59C3135A21CA5A7EF15ADA945B34BF5B8D805BE4DF5C3AEA5C8FA95CE3265D356C5D86835DD6735E25455E73005EBFAD5F0B525F55F75F9FA25FE85A60302460770860BD0A61023061467F6189FD61CCAE620E98624FBF62902762CFD5630ECD634D12638AA963C7966403DC643F7F647A8264B4E864EEB56527EC6560906598A365D029660724663D9766738566A8F066DDDA6712476746386779AF67ACAF67DF3A6811526842FA68743268A4FC68D55C6905536934E169640A6992CF69C13169EF326A1CD46A4A186A76FF6AA38C6ACFC0\\\";\\n\\n /// @notice Approximates log2 * 1M\\n /// @param _num number to take log2 * 1M of\\n /// @return approximate log2 times 1M\\n function log2ApproxTimes1M(uint256 _num) public pure returns (uint256) {\\n require(_num > 0, \\\"Number cannot be zero\\\");\\n uint256 leading = 0;\\n\\n if (_num == 1) return 0;\\n\\n while (_num > 128) {\\n _num = _num >> 1;\\n leading += 1;\\n }\\n return (leading * uint256(1000000)) + (getLog2TableTimes1M(_num));\\n }\\n\\n /// @notice navigates log2tableTimes1M\\n /// @param _num number to take log2 of\\n /// @return result after table look-up\\n function getLog2TableTimes1M(uint256 _num) public pure returns (uint256) {\\n bytes3 result = 0;\\n for (uint8 i = 0; i < 3; i++) {\\n bytes3 tempResult = log2tableTimes1M[(_num - 1) * 3 + i];\\n result = result | (tempResult >> (i * 8));\\n }\\n\\n return uint256(uint24(result));\\n }\\n\\n /// @notice get floor of log2 of number\\n /// @param _num number to take floor(log2) of\\n /// @return floor(log2) of _num\\n function getLog2Floor(uint256 _num) public pure returns (uint8) {\\n require(_num != 0, \\\"log of zero is undefined\\\");\\n\\n return uint8(255 - clz(_num));\\n }\\n\\n /// @notice checks if a number is Power of 2\\n /// @param _num number to check\\n /// @return true if number is power of 2, false if not\\n function isPowerOf2(uint256 _num) public pure returns (bool) {\\n if (_num == 0) return false;\\n\\n return _num & (_num - 1) == 0;\\n }\\n\\n /// @notice count trailing zeros\\n /// @param _num number you want the ctz of\\n /// @dev this a binary search implementation\\n function ctz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { n = n + 128; _num = _num >> 128; }\\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) { n = n + 64; _num = _num >> 64; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) { n = n + 32; _num = _num >> 32; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) { n = n + 16; _num = _num >> 16; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) { n = n + 8; _num = _num >> 8; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) { n = n + 4; _num = _num >> 4; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) { n = n + 2; _num = _num >> 2; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n\\n /// @notice count leading zeros\\n /// @param _num number you want the clz of\\n /// @dev this a binary search implementation\\n function clz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 == 0) { n = n + 128; _num = _num << 128; }\\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) { n = n + 64; _num = _num << 64; }\\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) { n = n + 32; _num = _num << 32; }\\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 16; _num = _num << 16; }\\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 8; _num = _num << 8; }\\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 4; _num = _num << 4; }\\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 2; _num = _num << 2; }\\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n}\\n\",\"keccak256\":\"0x28b74012e966438edff701decdc5ffd207b3f0244af65fbd7d397050986e58d4\",\"license\":\"Apache-2.0\"},\"@cartesi/util/contracts/Merkle.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Library for Merkle proofs\\npragma solidity ^0.8.0;\\n\\nimport \\\"./CartesiMath.sol\\\";\\n\\nlibrary Merkle {\\n using CartesiMath for uint256;\\n\\n uint128 constant L_WORD_SIZE = 3; // word = 8 bytes, log = 3\\n // number of hashes in EMPTY_TREE_HASHES\\n uint128 constant EMPTY_TREE_SIZE = 1952; // 61*32=1952. 32 bytes per 61 indexes (64 words)\\n\\n // merkle root hashes of trees of zero concatenated\\n // 32 bytes for each root, first one is keccak(0), second one is\\n // keccak(keccack(0), keccak(0)) and so on\\n\\n bytes constant EMPTY_TREE_HASHES =\\n hex\\\"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce4d9470a821fbe90117ec357e30bad9305732fb19ddf54a07dd3e29f440619254ae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a233fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9c37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e68e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e30930b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90cd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efed8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0c9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e6163e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b72122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046f7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec517a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca892b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e152499af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f27d86025599a41233848702f0cfc0437b445682df51147a632a0a083d2d38b5e13e466a8935afff58bb533b3ef5d27fba63ee6b0fd9e67ff20af9d50deee3f8bf065ec220c1fd4ba57e341261d55997f85d66d32152526736872693d2b437a233e2337b715f6ac9a6a272622fdc2d67fcfe1da3459f8dab4ed7e40a657a54c36766c5e8ac9a88b35b05c34747e6507f6b044ab66180dc76ac1a696de03189593fedc0d0dbbd855c8ead673544899b0960e4a5a7ca43b4ef90afe607de7698caefdc242788f654b57a4fb32a71b335ef6ff9a4cc118b282b53bdd6d6192b7a82c3c5126b9c7e33c8e5a5ac9738b8bd31247fb7402054f97b573e8abb9faad219f4fd085aceaa7f542d787ee4196d365f3cc566e7bbcfbfd451230c48d804c017d21e2d8fa914e2559bb72bf0ab78c8ab92f00ef0d0d576eccdd486b64138a4172674857e543d1d5b639058dd908186597e366ad5f3d9c7ceaff44d04d1550b8d33abc751df07437834ba5acb32328a396994aebb3c40f759c2d6d7a3cb5377e55d5d218ef5a296dda8ddc355f3f50c3d0b660a51dfa4d98a6a5a33564556cf83c1373a814641d6a1dcef97b883fee61bb84fe60a3409340217e629cc7e4dcc93b85d8820921ff5826148b60e6939acd7838e1d7f20562bff8ee4b5ec4a05ad997a57b9796fdcb2eda87883c2640b072b140b946bfdf6575cacc066fdae04f6951e63624cbd316a677cad529bbe4e97b9144e4bc06c4afd1de55dd3e1175f90423847a230d34dfb71ed56f2965a7f6c72e6aa33c24c303fd67745d632656c5ef90bec80f4f5d1daa251988826cef375c81c36bf457e09687056f924677cb0bccf98dff81e014ce25f2d132497923e267363963cdf4302c5049d63131dc03fd95f65d8b6aa5934f817252c028c90f56d413b9d5d10d89790707dae2fabb249f649929927c21dd71e3f656826de5451c5da375aadecbd59d5ebf3a31fae65ac1b316a1611f1b276b26530f58d7247df459ce1f86db1d734f6f811932f042cee45d0e455306d01081bc3384f82c5fb2aacaa19d89cdfa46cc916eac61121475ba2e6191b4feecbe1789717021a158ace5d06744b40f551076b67cd63af60007f8c99876e1424883a45ec49d497ddaf808a5521ca74a999ab0b3c7aa9c80f85e93977ec61ce68b20307a1a81f71ca645b568fcd319ccbb5f651e87b707d37c39e15f945ea69e2f7c7d2ccc85b7e654c07e96f0636ae4044fe0e38590b431795ad0f8647bdd613713ada493cc17efd313206380e6a685b8198475bbd021c6e9d94daab2214947127506073e44d5408ba166c512a0b86805d07f5a44d3c41706be2bc15e712e55805248b92e8677d90f6d284d1d6ffaff2c430657042a0e82624fa3717b06cc0a6fd12230ea586dae83019fb9e06034ed2803c98d554b93c9a52348cafff75c40174a91f9ae6b8647854a156029f0b88b83316663ce574a4978277bb6bb27a31085634b6ec78864b6d8201c7e93903d75815067e378289a3d072ae172dafa6a452470f8d645bebfad9779594fc0784bb764a22e3a8181d93db7bf97893c414217a618ccb14caa9e92e8c61673afc9583662e812adba1f87a9c68202d60e909efab43c42c0cb00695fc7f1ffe67c75ca894c3c51e1e5e731360199e600f6ced9a87b2a6a87e70bf251bb5075ab222138288164b2eda727515ea7de12e2496d4fe42ea8d1a120c03cf9c50622c2afe4acb0dad98fd62d07ab4e828a94495f6d1ab973982c7ccbe6c1fae02788e4422ae22282fa49cbdb04ba54a7a238c6fc41187451383460762c06d1c8a72b9cd718866ad4b689e10c9a8c38fe5ef045bd785b01e980fc82c7e3532ce81876b778dd9f1ceeba4478e86411fb6fdd790683916ca832592485093644e8760cd7b4c01dba1ccc82b661bf13f0e3f34acd6b88\\\";\\n\\n /// @notice Gets merkle root hash of drive with a replacement\\n /// @param _position position of _drive\\n /// @param _logSizeOfReplacement log2 of size the replacement\\n /// @param _logSizeOfFullDrive log2 of size the full drive, which can be the entire machine\\n /// @param _replacement hash of the replacement\\n /// @param siblings of replacement that merkle root can be calculated\\n function getRootAfterReplacementInDrive(\\n uint256 _position,\\n uint256 _logSizeOfReplacement,\\n uint256 _logSizeOfFullDrive,\\n bytes32 _replacement,\\n bytes32[] calldata siblings\\n ) public pure returns (bytes32) {\\n require(\\n _logSizeOfFullDrive >= _logSizeOfReplacement &&\\n _logSizeOfReplacement >= 3 &&\\n _logSizeOfFullDrive <= 64,\\n \\\"3 <= logSizeOfReplacement <= logSizeOfFullDrive <= 64\\\"\\n );\\n\\n uint256 size = 1 << _logSizeOfReplacement;\\n\\n require(((size - 1) & _position) == 0, \\\"Position is not aligned\\\");\\n require(\\n siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement,\\n \\\"Proof length does not match\\\"\\n );\\n\\n for (uint256 i; i < siblings.length; i++) {\\n if ((_position & (size << i)) == 0) {\\n _replacement = keccak256(\\n abi.encodePacked(_replacement, siblings[i])\\n );\\n } else {\\n _replacement = keccak256(\\n abi.encodePacked(siblings[i], _replacement)\\n );\\n }\\n }\\n\\n return _replacement;\\n }\\n\\n /// @notice Gets precomputed hash of zero in empty tree hashes\\n /// @param _index of hash wanted\\n /// @dev first index is keccak(0), second index is keccak(keccak(0), keccak(0))\\n function getEmptyTreeHashAtIndex(uint256 _index)\\n public\\n pure\\n returns (bytes32)\\n {\\n uint256 start = _index * 32;\\n require(EMPTY_TREE_SIZE >= start + 32, \\\"index out of bounds\\\");\\n bytes32 hashedZeros;\\n bytes memory zeroTree = EMPTY_TREE_HASHES;\\n\\n // first word is length, then skip index words\\n assembly {\\n hashedZeros := mload(add(add(zeroTree, 0x20), start))\\n }\\n return hashedZeros;\\n }\\n\\n /// @notice get merkle root of generic array of bytes\\n /// @param _data array of bytes to be merklelized\\n /// @param _log2Size log2 of total size of the drive\\n /// @dev _data is padded with zeroes until is multiple of 8\\n /// @dev root is completed with zero tree until log2size is complete\\n /// @dev hashes are taken word by word (8 bytes by 8 bytes)\\n function getMerkleRootFromBytes(bytes calldata _data, uint256 _log2Size)\\n public\\n pure\\n returns (bytes32)\\n {\\n require(_log2Size >= 3 && _log2Size <= 64, \\\"range of log2Size: [3,64]\\\");\\n\\n // if _data is empty return pristine drive of size log2size\\n if (_data.length == 0) return getEmptyTreeHashAtIndex(_log2Size - 3);\\n\\n // total size of the drive in words\\n uint256 size = 1 << (_log2Size - 3);\\n require(\\n size << L_WORD_SIZE >= _data.length,\\n \\\"data is bigger than drive\\\"\\n );\\n // the stack depth is log2(_data.length / 8) + 2\\n uint256 stack_depth = 2 +\\n ((_data.length) >> L_WORD_SIZE).getLog2Floor();\\n bytes32[] memory stack = new bytes32[](stack_depth);\\n\\n uint256 numOfHashes; // total number of hashes on stack (counting levels)\\n uint256 stackLength; // total length of stack\\n uint256 numOfJoins; // number of hashes of the same level on stack\\n uint256 topStackLevel; // hash level of the top of the stack\\n\\n while (numOfHashes < size) {\\n if ((numOfHashes << L_WORD_SIZE) < _data.length) {\\n // we still have words to hash\\n stack[stackLength] = getHashOfWordAtIndex(_data, numOfHashes);\\n numOfHashes++;\\n\\n numOfJoins = numOfHashes;\\n } else {\\n // since padding happens in hashOfWordAtIndex function\\n // we only need to complete the stack with pre-computed\\n // hash(0), hash(hash(0),hash(0)) and so on\\n topStackLevel = numOfHashes.ctz();\\n\\n stack[stackLength] = getEmptyTreeHashAtIndex(topStackLevel);\\n\\n //Empty Tree Hash summarizes many hashes\\n numOfHashes = numOfHashes + (1 << topStackLevel);\\n numOfJoins = numOfHashes >> topStackLevel;\\n }\\n\\n stackLength++;\\n\\n // while there are joins, hash top of stack together\\n while (numOfJoins & 1 == 0) {\\n bytes32 h2 = stack[stackLength - 1];\\n bytes32 h1 = stack[stackLength - 2];\\n\\n stack[stackLength - 2] = keccak256(abi.encodePacked(h1, h2));\\n stackLength = stackLength - 1; // remove hashes from stack\\n\\n numOfJoins = numOfJoins >> 1;\\n }\\n }\\n require(stackLength == 1, \\\"stack error\\\");\\n\\n return stack[0];\\n }\\n\\n /// @notice Get the hash of a word in an array of bytes\\n /// @param _data array of bytes\\n /// @param _wordIndex index of word inside the bytes to get the hash of\\n /// @dev if word is incomplete (< 8 bytes) it gets padded with zeroes\\n function getHashOfWordAtIndex(bytes calldata _data, uint256 _wordIndex)\\n public\\n pure\\n returns (bytes32)\\n {\\n uint256 start = _wordIndex << L_WORD_SIZE;\\n uint256 end = start + (1 << L_WORD_SIZE);\\n\\n // TODO: in .lua this just returns zero, but this might be more consistent\\n require(start <= _data.length, \\\"word out of bounds\\\");\\n\\n if (end <= _data.length) {\\n return keccak256(abi.encodePacked(_data[start:end]));\\n }\\n\\n // word is incomplete\\n // fill paddedSlice with incomplete words - the rest is going to be bytes(0)\\n bytes memory paddedSlice = new bytes(8);\\n uint256 remaining = _data.length - start;\\n\\n for (uint256 i; i < remaining; i++) {\\n paddedSlice[i] = _data[start + i];\\n }\\n\\n return keccak256(paddedSlice);\\n }\\n\\n /// @notice Calculate the root of Merkle tree from an array of power of 2 elements\\n /// @param hashes The array containing power of 2 elements\\n /// @return byte32 the root hash being calculated\\n function calculateRootFromPowerOfTwo(bytes32[] memory hashes)\\n public\\n pure\\n returns (bytes32)\\n {\\n // revert when the input is not of power of 2\\n require((hashes.length).isPowerOf2(), \\\"array len not power of 2\\\");\\n\\n if (hashes.length == 1) {\\n return hashes[0];\\n } else {\\n bytes32[] memory newHashes = new bytes32[](hashes.length >> 1);\\n\\n for (uint256 i; i < hashes.length; i += 2) {\\n newHashes[i >> 1] = keccak256(\\n abi.encodePacked(hashes[i], hashes[i + 1])\\n );\\n }\\n\\n return calculateRootFromPowerOfTwo(newHashes);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe9896db44cc4dab335a3e776c629186824823d316d902b2efecb4b0a3e3dfdb7\",\"license\":\"Apache-2.0\"},\"contracts/DisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title DisputeManager\\npragma solidity >=0.7.0;\\n\\ninterface DisputeManager {\\n function initiateDispute(\\n bytes32[2] memory _claims,\\n address payable[2] memory _claimers\\n ) external;\\n}\\n\",\"keccak256\":\"0xaf5e1b8531469091519f02126a58161788980015d696bf95ba59679ff6366ec1\",\"license\":\"Apache-2.0\"},\"contracts/DisputeManagerImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title DisputeManager\\npragma solidity ^0.8.0;\\n\\nimport \\\"./DisputeManager.sol\\\";\\nimport \\\"./Rollups.sol\\\";\\n\\ncontract DisputeManagerImpl is DisputeManager {\\n Rollups immutable rollups; // rollups contract\\n\\n /// @notice functions modified by onlyRollups will only be executed if\\n // they're called by Rollups contract, otherwise it will throw an exception\\n modifier onlyRollups {\\n require(\\n msg.sender == address(rollups),\\n \\\"Only rollups can call this functions\\\"\\n );\\n _;\\n }\\n\\n constructor(address _rollups) {\\n rollups = Rollups(_rollups);\\n }\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param _claims conflicting claims\\n /// @param _claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of _claimers array\\n function initiateDispute(\\n bytes32[2] memory _claims,\\n address payable[2] memory _claimers\\n ) public override onlyRollups {\\n rollups.resolveDispute(_claimers[0], _claimers[1], _claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0xb7c09b049c624a14302a58fe33006581a9391be12cc697c611bb0aaf6794a923\",\"license\":\"Apache-2.0\"},\"contracts/Input.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input\\npragma solidity >=0.7.0;\\n\\ninterface Input {\\n /// @notice adds input to correct inbox\\n /// @param _input bytes array of input\\n /// @return merkle root hash of input\\n /// @dev msg.sender and timestamp are preppended log2 size\\n /// has to be calculated offchain taking that into account\\n function addInput(bytes calldata _input) external returns (bytes32);\\n\\n /// @notice returns input from correct input inbox\\n /// @param _index position of the input on inbox\\n /// @return root hash of input\\n function getInput(uint256 _index) external view returns (bytes32);\\n\\n /// @notice returns number of inputs on correct inbox\\n /// @return number of inputs of non active inbox\\n function getNumberOfInputs() external view returns (uint256);\\n\\n /// @notice returns active current inbox index\\n /// @return index of current active inbox\\n function getCurrentInbox() external view returns (uint256);\\n\\n /// @notice called whenever there is a new input accumulation epoch\\n /// @dev has to be called even if new input accumulation happens\\n /// implicitly due to a new epoch\\n function onNewInputAccumulation() external;\\n\\n /// @notice called when a new epoch begins, clears correct input box\\n function onNewEpoch() external;\\n\\n /// @notice input added\\n /// @param _epochNumber which epoch this input belongs to\\n /// @param _inputIndex index of the input just added\\n /// @param _sender msg.sender\\n /// @param _timestamp block.timestamp\\n /// @param _input input data\\n event InputAdded(\\n uint256 indexed _epochNumber,\\n uint256 indexed _inputIndex,\\n address _sender,\\n uint256 _timestamp,\\n bytes _input\\n );\\n}\\n\",\"keccak256\":\"0x77b327595fd5b8a5d16f4cb42187068288c82d21f17581117d07f449d7b75939\",\"license\":\"Apache-2.0\"},\"contracts/InputImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input Implementation\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Input.sol\\\";\\nimport \\\"./Rollups.sol\\\";\\n\\ncontract InputImpl is Input {\\n Rollups immutable rollups; // rollups contract using this input contract\\n\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n\\n uint256 immutable inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n\\n /// @param _rollups address of rollups contract that will manage inboxes\\n /// @param _log2Size size of the input drive of the machine\\n constructor(address _rollups, uint256 _log2Size) {\\n require(_log2Size >= 3 && _log2Size <= 64, \\\"log size: [3,64]\\\");\\n\\n rollups = Rollups(_rollups);\\n inputDriveSize = (1 << _log2Size);\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param _input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n // the offchain machine has a 8 byte word\\n function addInput(bytes calldata _input) public override returns (bytes32) {\\n require(\\n _input.length > 0 && _input.length <= inputDriveSize,\\n \\\"input len: (0,driveSize]\\\"\\n );\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollups.notifyInput()) {\\n swapInputBox();\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = currentInputBox == 0 ? inputBox0 : inputBox1;\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata =\\n keccak256(\\n abi.encode(\\n msg.sender,\\n block.number,\\n block.timestamp,\\n rollups.getCurrentEpoch(), // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(_input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n rollups.getCurrentEpoch(),\\n inputBox.length - 1,\\n msg.sender,\\n block.timestamp,\\n _input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param _index index of input inside that inbox\\n /// @return hash of input at index _index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(uint256 _index) public view override returns (bytes32) {\\n return currentInputBox == 0 ? inputBox1[_index] : inputBox0[_index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs() public view override returns (uint256) {\\n return currentInputBox == 0 ? inputBox1.length : inputBox0.length;\\n }\\n\\n /// @notice get inbox currently receiveing inputs\\n /// @return input inbox currently receiveing inputs\\n function getCurrentInbox() public view override returns (uint256) {\\n return currentInputBox;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @dev can only be called by Rollups contract\\n function onNewInputAccumulation() public override {\\n onlyRollups();\\n swapInputBox();\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @dev can only be called by Rollups contract\\n function onNewEpoch() public override {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n onlyRollups();\\n currentInputBox == 0 ? delete inputBox1 : delete inputBox0;\\n }\\n\\n /// @notice check if message sender is Rollups\\n function onlyRollups() internal view {\\n require(msg.sender == address(rollups), \\\"Only rollups\\\");\\n }\\n\\n /// @notice changes current input box\\n function swapInputBox() internal {\\n currentInputBox == 0 ? currentInputBox = 1 : currentInputBox = 0;\\n }\\n}\\n\",\"keccak256\":\"0x5bfff1c97a0317a02ac73bf7d85cafecdf6e44901021eb9690afca831abee0ef\",\"license\":\"Apache-2.0\"},\"contracts/Output.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output\\npragma solidity >=0.7.0;\\n\\ninterface Output {\\n /// @param _epochIndex which epoch the output belongs to\\n /// @param _inputIndex which input, inside the epoch, the output belongs to\\n /// @param _outputIndex index of output inside the input\\n /// @param _outputMetadataArrayDriveHash hash of the output's metadata drive where this output is in\\n /// @param _epochVoucherDriveHash merkle root of all epoch's voucher metadata drive hashes\\n /// @param _epochNoticeDriveHash hash of NoticeMetadataArrayDrive\\n /// @param _epochMachineFinalState hash of the machine state claimed this epoch\\n /// @param _outputMetadataProof proof that this output's metadata is in meta data drive\\n /// @param _epochOutputDriveProof proof that this output metadata drive is in epoch's Output drive\\n struct OutputValidityProof {\\n uint256 epochIndex;\\n uint256 inputIndex;\\n uint256 outputIndex;\\n bytes32 outputMetadataArrayDriveHash;\\n bytes32 epochVoucherDriveHash;\\n bytes32 epochNoticeDriveHash;\\n bytes32 epochMachineFinalState;\\n bytes32[] outputMetadataProof;\\n bytes32[] epochOutputDriveProof;\\n }\\n\\n /// @notice executes voucher\\n /// @param _destination address that will execute the payload\\n /// @param _payload payload to be executed by destination\\n /// @param _v validity proof for this encoded voucher\\n /// @return true if voucher was executed successfully\\n /// @dev vouchers can only be executed once\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n OutputValidityProof calldata _v\\n ) external returns (bool);\\n\\n /// @notice called by rollups when an epoch is finalized\\n /// @param _epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(bytes32 _epochHash) external;\\n\\n /// @notice get number of finalized epochs\\n function getNumberOfFinalizedEpochs() external view returns (uint256);\\n\\n /// @notice get log2 size of voucher metadata drive\\n function getVoucherMetadataLog2Size()\\n external\\n pure\\n returns (uint256);\\n\\n /// @notice get log2 size of epoch voucher drive\\n function getEpochVoucherLog2Size()\\n external\\n pure\\n returns (uint256);\\n\\n /// @notice get log2 size of notice metadata drive\\n function getNoticeMetadataLog2Size()\\n external\\n pure\\n returns (uint256);\\n\\n /// @notice get log2 size of epoch notice drive\\n function getEpochNoticeLog2Size()\\n external\\n pure\\n returns (uint256);\\n\\n event VoucherExecuted(uint256 voucherPosition);\\n}\\n\",\"keccak256\":\"0xe3434f190b59d71f0deab32ee8d29df20a818758bc5a540ac69e0a128d3f2992\",\"license\":\"Apache-2.0\"},\"contracts/OutputImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output Implementation\\npragma solidity ^0.8.0;\\n\\nimport \\\"@cartesi/util/contracts/Bitmask.sol\\\";\\nimport \\\"@cartesi/util/contracts/Merkle.sol\\\";\\n\\nimport \\\"./Output.sol\\\";\\n\\ncontract OutputImpl is Output {\\n // Here we only need 248 bits as keys in the mapping, but we use 256 bits for gas optimization\\n using Bitmask for mapping(uint256 => uint256);\\n\\n uint256 constant KECCAK_LOG2_SIZE = 5; // keccak log2 size\\n\\n // max size of voucher metadata drive 32 * (2^16) bytes\\n uint256 constant VOUCHER_METADATA_LOG2_SIZE = 21;\\n // max size of epoch voucher drive 32 * (2^32) bytes\\n uint256 constant EPOCH_VOUCHER_LOG2_SIZE = 37;\\n\\n // max size of notice metadata drive 32 * (2^16) bytes\\n uint256 constant NOTICE_METADATA_LOG2_SIZE = 21;\\n // max size of epoch notice drive 32 * (2^32) bytes\\n uint256 constant EPOCH_NOTICE_LOG2_SIZE = 37;\\n\\n address immutable rollups; // rollups contract using this validator\\n mapping(uint256 => uint256) internal voucherBitmask;\\n bytes32[] epochHashes;\\n\\n bool lock; //reentrancy lock\\n\\n /// @notice functions modified by noReentrancy are not subject to recursion\\n modifier noReentrancy() {\\n require(!lock, \\\"reentrancy not allowed\\\");\\n lock = true;\\n _;\\n lock = false;\\n }\\n\\n /// @notice functions modified by onlyRollups will only be executed if\\n // they're called by Rollups contract, otherwise it will throw an exception\\n modifier onlyRollups {\\n require(msg.sender == rollups, \\\"Only rollups\\\");\\n _;\\n }\\n\\n // @notice creates OutputImpl contract\\n // @params _rollups address of rollupscontract\\n constructor(address _rollups)\\n {\\n rollups = _rollups;\\n }\\n\\n /// @notice executes voucher\\n /// @param _encodedVoucher encoded voucher mocking the behaviour\\n // of abi.encode(address _destination, bytes _payload)\\n /// @param _v validity proof for this encoded voucher\\n /// @return true if voucher was executed successfully\\n /// @dev vouchers can only be executed once\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n OutputValidityProof calldata _v\\n ) public override noReentrancy returns (bool) {\\n bytes memory encodedVoucher = abi.encode(_destination, _payload);\\n\\n // check if validity proof matches the voucher provided\\n isValidVoucherProof(encodedVoucher, epochHashes[_v.epochIndex], _v);\\n\\n uint256 voucherPosition =\\n getBitMaskPosition(_v.outputIndex, _v.inputIndex, _v.epochIndex);\\n\\n // check if voucher has been executed\\n require(\\n !voucherBitmask.getBit(voucherPosition),\\n \\\"re-execution not allowed\\\"\\n );\\n\\n // execute voucher\\n (bool succ, ) = address(_destination).call(_payload);\\n\\n // if properly executed, mark it as executed and emit event\\n if (succ) {\\n voucherBitmask.setBit(voucherPosition, true);\\n emit VoucherExecuted(voucherPosition);\\n }\\n\\n return succ;\\n }\\n\\n /// @notice called by rollups when an epoch is finalized\\n /// @param _epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(bytes32 _epochHash) public override onlyRollups {\\n epochHashes.push(_epochHash);\\n }\\n\\n /// @notice functions modified by isValidProof will only be executed if\\n // the validity proof is valid\\n // @dev _epochOutputDriveHash must be _v.epochVoucherDriveHash or\\n // or _v.epochNoticeDriveHash\\n function isValidProof(\\n bytes memory _encodedOutput,\\n bytes32 _epochHash,\\n bytes32 _epochOutputDriveHash,\\n uint256 _epochOutputLog2Size,\\n uint256 _outputMetadataLog2Size,\\n OutputValidityProof calldata _v\\n ) internal pure returns (bool) {\\n // prove that outputs hash is represented in a finalized epoch\\n require(\\n keccak256(\\n abi.encodePacked(\\n _v.epochVoucherDriveHash,\\n _v.epochNoticeDriveHash,\\n _v.epochMachineFinalState\\n )\\n ) == _epochHash,\\n \\\"epochHash incorrect\\\"\\n );\\n\\n // prove that output metadata drive is contained in epoch's output drive\\n require(\\n Merkle.getRootAfterReplacementInDrive(\\n getIntraDrivePosition(_v.inputIndex, KECCAK_LOG2_SIZE),\\n KECCAK_LOG2_SIZE,\\n _epochOutputLog2Size,\\n keccak256(abi.encodePacked(_v.outputMetadataArrayDriveHash)),\\n _v.epochOutputDriveProof\\n ) == _epochOutputDriveHash,\\n \\\"epochOutputDriveHash incorrect\\\"\\n );\\n\\n // The hash of the output is converted to bytes (abi.encode) and\\n // treated as data. The metadata output drive stores that data while\\n // being indifferent to its contents. To prove that the received\\n // output is contained in the metadata output drive we need to\\n // prove that x, where:\\n // x = keccak(\\n // keccak(\\n // keccak(hashOfOutput[0:7]),\\n // keccak(hashOfOutput[8:15])\\n // ),\\n // keccak(\\n // keccak(hashOfOutput[16:23]),\\n // keccak(hashOfOutput[24:31])\\n // )\\n // )\\n // is contained in it. We can't simply use hashOfOutput because the\\n // log2size of the leaf is three (8 bytes) not five (32 bytes)\\n bytes32 merkleRootOfHashOfOutput =\\n Merkle.getMerkleRootFromBytes(\\n abi.encodePacked(keccak256(_encodedOutput)),\\n KECCAK_LOG2_SIZE\\n );\\n\\n // prove that merkle root hash of bytes(hashOfOutput) is contained\\n // in the output metadata array drive\\n require(\\n Merkle.getRootAfterReplacementInDrive(\\n getIntraDrivePosition(_v.outputIndex, KECCAK_LOG2_SIZE),\\n KECCAK_LOG2_SIZE,\\n _outputMetadataLog2Size,\\n merkleRootOfHashOfOutput,\\n _v.outputMetadataProof\\n ) == _v.outputMetadataArrayDriveHash,\\n \\\"outputMetadataArrayDriveHash incorrect\\\"\\n );\\n\\n return true;\\n }\\n\\n /// @notice functions modified by isValidVoucherProof will only be executed if\\n // the validity proof is valid\\n function isValidVoucherProof(\\n bytes memory _encodedVoucher,\\n bytes32 _epochHash,\\n OutputValidityProof calldata _v\\n )\\n public\\n pure\\n returns (bool)\\n {\\n return isValidProof(\\n _encodedVoucher,\\n _epochHash,\\n _v.epochVoucherDriveHash,\\n EPOCH_VOUCHER_LOG2_SIZE,\\n VOUCHER_METADATA_LOG2_SIZE,\\n _v\\n );\\n }\\n\\n /// @notice functions modified by isValidNoticeProof will only be executed if\\n // the validity proof is valid\\n function isValidNoticeProof(\\n bytes memory _encodedNotice,\\n bytes32 _epochHash,\\n OutputValidityProof calldata _v\\n )\\n public\\n pure\\n returns (bool)\\n {\\n return isValidProof(\\n _encodedNotice,\\n _epochHash,\\n _v.epochNoticeDriveHash,\\n EPOCH_NOTICE_LOG2_SIZE,\\n NOTICE_METADATA_LOG2_SIZE,\\n _v\\n );\\n }\\n\\n /// @notice get voucher position on bitmask\\n /// @param _voucher of voucher inside the input\\n /// @param _input which input, inside the epoch, the voucher belongs to\\n /// @param _epoch which epoch the voucher belongs to\\n /// @return position of that voucher on bitmask\\n function getBitMaskPosition(\\n uint256 _voucher,\\n uint256 _input,\\n uint256 _epoch\\n ) public pure returns (uint256) {\\n // voucher * 2 ** 128 + input * 2 ** 64 + epoch\\n // this can't overflow because its impossible to have > 2**128 vouchers\\n return (((_voucher << 128) | (_input << 64)) | _epoch);\\n }\\n\\n /// @notice returns the position of a intra drive on a drive\\n // with contents with the same size\\n /// @param _index index of intra drive\\n /// @param _log2Size of intra drive\\n function getIntraDrivePosition(uint256 _index, uint256 _log2Size)\\n public\\n pure\\n returns (uint256)\\n {\\n return (_index << _log2Size);\\n }\\n\\n /// @notice get number of finalized epochs\\n function getNumberOfFinalizedEpochs()\\n public\\n view\\n override\\n returns (uint256)\\n {\\n return epochHashes.length;\\n }\\n\\n /// @notice get log2 size of voucher metadata drive\\n function getVoucherMetadataLog2Size()\\n public\\n pure\\n override\\n returns (uint256)\\n {\\n return VOUCHER_METADATA_LOG2_SIZE;\\n }\\n\\n /// @notice get log2 size of epoch voucher drive\\n function getEpochVoucherLog2Size()\\n public\\n pure\\n override\\n returns (uint256)\\n {\\n return EPOCH_VOUCHER_LOG2_SIZE;\\n }\\n\\n /// @notice get log2 size of notice metadata drive\\n function getNoticeMetadataLog2Size()\\n public\\n pure\\n override\\n returns (uint256)\\n {\\n return NOTICE_METADATA_LOG2_SIZE;\\n }\\n\\n /// @notice get log2 size of epoch notice drive\\n function getEpochNoticeLog2Size()\\n public\\n pure\\n override\\n returns (uint256)\\n {\\n return EPOCH_NOTICE_LOG2_SIZE;\\n }\\n}\\n\",\"keccak256\":\"0xb9f9853a59073d3c474bfae2eb1aa3d8cb9e9a702e05e17e076e5214392e68d2\",\"license\":\"Apache-2.0\"},\"contracts/Rollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Interface Rollups contract\\npragma solidity >=0.7.0;\\n\\nimport \\\"./Input.sol\\\";\\nimport \\\"./Output.sol\\\";\\nimport \\\"./ValidatorManager.sol\\\";\\n\\ninterface Rollups {\\n // InputAccumulation - Inputs being accumulated for currrent epoch\\n // AwaitingConsensus - No disagreeing claims (or no claims)\\n // AwaitingDispute - Waiting for dispute to be over\\n // inputs received during InputAccumulation will be included in the\\n // current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n // are accumulated for the next epoch\\n enum Phase {InputAccumulation, AwaitingConsensus, AwaitingDispute}\\n\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n // and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @dev can only be called by input contract\\n function notifyInput() external returns (bool);\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param _winner winner of dispute\\n /// @param _loser lose of sipute\\n /// @param _winningClaim initial claim of winning validator\\n /// @dev can only by the dispute contract\\n function resolveDispute(\\n address payable _winner,\\n address payable _loser,\\n bytes32 _winningClaim\\n ) external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n // of finalized epochs array, else there are two epochs two non\\n // finalized epochs, one awaiting consensus/dispute and another\\n // accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice returns address of input contract\\n function getInputAddress() external view returns (address);\\n\\n /// @notice returns address of output contract\\n function getOutputAddress() external view returns (address);\\n\\n /// @notice returns address of validator manager contract\\n function getValidatorManagerAddress() external view returns (address);\\n\\n /// @notice returns address of dispute manager contract\\n function getDisputeManagerAddress() external view returns (address);\\n\\n // events\\n\\n /// @notice contract created\\n /// @param _input address of input contract\\n /// @param _output address of output contract\\n /// @param _validatorManager address of validatorManager contract\\n /// @param _disputeManager address of disputeManager contract\\n /// @param _inputDuration duration of input accumulation phase in seconds\\n /// @param _challengePeriod duration of challenge period in seconds\\n event RollupsCreated(\\n address _input,\\n address _output,\\n address _validatorManager,\\n address _disputeManager,\\n uint256 _inputDuration,\\n uint256 _challengePeriod\\n );\\n\\n /// @notice claim submitted\\n /// @param _epochHash claim being submitted by this epoch\\n /// @param _claimer address of current claimer\\n /// @param _epochNumber number of the epoch being submitted\\n event Claim(uint256 indexed _epochNumber, address _claimer, bytes32 _epochHash);\\n\\n /// @notice epoch finalized\\n /// @param _epochNumber number of the epoch being finalized\\n /// @param _epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed _epochNumber, bytes32 _epochHash);\\n\\n /// @notice dispute resolved\\n /// @param _winner winner of dispute\\n /// @param _loser loser of dispute\\n /// @param _winningClaim initial claim of winning validator\\n event ResolveDispute(\\n address _winner,\\n address _loser,\\n bytes32 _winningClaim\\n );\\n\\n /// @notice phase change\\n /// @param _newPhase new phase\\n event PhaseChange(Phase _newPhase);\\n}\\n\",\"keccak256\":\"0xbe254b4a01ae4b5e77d300c8cb456ac5ea8fa162a028b824c0987ba8524aae7a\",\"license\":\"Apache-2.0\"},\"contracts/RollupsImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups Impl\\npragma solidity ^0.8.0;\\n\\nimport \\\"./InputImpl.sol\\\";\\nimport \\\"./OutputImpl.sol\\\";\\nimport \\\"./ValidatorManagerImpl.sol\\\";\\nimport \\\"./Rollups.sol\\\";\\nimport \\\"./DisputeManagerImpl.sol\\\";\\n\\ncontract RollupsImpl is Rollups {\\n ////\\n // All claims agreed OR challenge period ended\\n // functions: claim() or finalizeEpoch()\\n // +--------------------------------------------------+\\n // | |\\n // +--------v-----------+ new input after IPAD +---------+----------+\\n // | +--------------------------->+ |\\n // START ---> | Input Accumulation | firt claim after IPAD | Awaiting Consensus |\\n // | +--------------------------->+ |\\n // +-+------------------+ +-----------------+--+\\n // ^ ^ |\\n // | dispute resolved | |\\n // | dispute resolved before challenge | |\\n // | after challenge +--------------------+ period ended | |\\n // | period ended | +---------------------+ |\\n // +----------------------+ Awaiting Dispute | |\\n // | +<-----------------------+\\n // +--------------------+ conflicting claim\\n ///\\n\\n InputImpl public input; // contract responsible for inputs\\n OutputImpl public output; // contract responsible for outputs\\n ValidatorManagerImpl public validatorManager; // contract responsible for validators\\n DisputeManagerImpl public disputeManager; // contract responsible for dispute resolution\\n\\n struct StorageVar {\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n StorageVar public storageVar;\\n\\n /// @notice functions modified by onlyInputContract can only be called\\n // by input contract\\n modifier onlyInputContract {\\n require(msg.sender == address(input), \\\"only Input Contract\\\");\\n _;\\n }\\n\\n /// @notice functions modified by onlyDisputeContract can only be called\\n // by dispute contract\\n modifier onlyDisputeContract {\\n require(msg.sender == address(disputeManager), \\\"only Dispute Contract\\\");\\n _;\\n }\\n\\n /// @notice creates contract\\n /// @param _inputDuration duration of input accumulation phase in seconds\\n /// @param _challengePeriod duration of challenge period in seconds\\n /// @param _inputLog2Size size of the input drive in this machine\\n /// @param _validators initial validator set\\n constructor(\\n uint256 _inputDuration,\\n uint256 _challengePeriod,\\n // input constructor variables\\n uint256 _inputLog2Size,\\n // validator manager constructor variables\\n address payable[] memory _validators\\n ) {\\n input = new InputImpl(address(this), _inputLog2Size);\\n output = new OutputImpl(address(this));\\n validatorManager = new ValidatorManagerImpl(address(this), _validators);\\n disputeManager = new DisputeManagerImpl(address(this));\\n\\n storageVar = StorageVar(\\n uint32(_inputDuration),\\n uint32(_challengePeriod),\\n uint32(block.timestamp),\\n 0,\\n uint32(Phase.InputAccumulation)\\n );\\n\\n emit RollupsCreated(\\n address(input),\\n address(output),\\n address(validatorManager),\\n address(disputeManager),\\n _inputDuration,\\n _challengePeriod\\n );\\n }\\n\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n // and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) public override {\\n ValidatorManager.Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n uint256 inputAccumulationStart = storageVar.inputAccumulationStart;\\n uint256 inputDuration = storageVar.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n currentPhase = Phase.AwaitingConsensus;\\n storageVar.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n\\n // warns input of new epoch\\n input.onNewInputAccumulation();\\n // update timestamp of sealing epoch proposal\\n storageVar.sealingEpochTimestamp = uint32(block.timestamp);\\n }\\n\\n require(\\n currentPhase == Phase.AwaitingConsensus,\\n \\\"Phase != AwaitingConsensus\\\"\\n );\\n (result, claims, claimers) = validatorManager.onClaim(\\n payable(msg.sender),\\n _epochHash\\n );\\n\\n // emit the claim event before processing it\\n // so if the epoch is finalized in this claim (consensus)\\n // the number of final epochs doesnt gets contaminated\\n emit Claim(output.getNumberOfFinalizedEpochs(), msg.sender, _epochHash);\\n\\n resolveValidatorResult(result, claims, claimers);\\n }\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() public override {\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n require(\\n currentPhase == Phase.AwaitingConsensus,\\n \\\"Phase != Awaiting Consensus\\\"\\n );\\n\\n uint256 sealingEpochTimestamp = storageVar.sealingEpochTimestamp;\\n uint256 challengePeriod = storageVar.challengePeriod;\\n require(\\n block.timestamp > sealingEpochTimestamp + challengePeriod,\\n \\\"Challenge period not over\\\"\\n );\\n\\n require(\\n validatorManager.getCurrentClaim() != bytes32(0),\\n \\\"No Claim to be finalized\\\"\\n );\\n\\n startNewEpoch();\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @dev can only be called by input contract\\n function notifyInput() public override onlyInputContract returns (bool) {\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n uint256 inputAccumulationStart = storageVar.inputAccumulationStart;\\n uint256 inputDuration = storageVar.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n storageVar.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param _winner winner of dispute\\n /// @param _loser loser of dispute\\n /// @param _winningClaim initial claim of winning validator\\n /// @dev can only be called by the dispute contract\\n function resolveDispute(\\n address payable _winner,\\n address payable _loser,\\n bytes32 _winningClaim\\n ) public override onlyDisputeContract {\\n ValidatorManager.Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n\\n (result, claims, claimers) = validatorManager.onDisputeEnd(\\n _winner,\\n _loser,\\n _winningClaim\\n );\\n\\n // restart challenge period\\n storageVar.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(_winner, _loser, _winningClaim);\\n resolveValidatorResult(result, claims, claimers);\\n }\\n\\n /// @notice starts new epoch\\n function startNewEpoch() internal {\\n // reset input accumulation start and deactivate challenge period start\\n storageVar.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n storageVar.inputAccumulationStart = uint32(block.timestamp);\\n storageVar.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManager.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output contract's storage\\n emit FinalizeEpoch(output.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n output.onNewEpoch(finalClaim);\\n input.onNewEpoch();\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param _result result from claim or dispute operation\\n /// @param _claims array of claims in case of new conflict\\n /// @param _claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n ValidatorManager.Result _result,\\n bytes32[2] memory _claims,\\n address payable[2] memory _claimers\\n ) internal {\\n if (_result == ValidatorManager.Result.NoConflict) {\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n storageVar.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (_result == ValidatorManager.Result.Consensus) {\\n startNewEpoch();\\n } else {\\n // for the case when _result == ValidatorManager.Result.Conflict\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n storageVar.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n disputeManager.initiateDispute(_claims, _claimers);\\n }\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n // of finalized epochs array, else there are two non finalized epochs,\\n // one awaiting consensus/dispute and another accumulating input\\n\\n function getCurrentEpoch() public view override returns (uint256) {\\n uint256 finalizedEpochs = output.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n\\n /// @notice returns address of input contract\\n function getInputAddress() public view override returns (address) {\\n return address(input);\\n }\\n\\n /// @notice returns address of output contract\\n function getOutputAddress() public view override returns (address) {\\n return address(output);\\n }\\n\\n /// @notice returns address of validator manager contract\\n function getValidatorManagerAddress()\\n public\\n view\\n override\\n returns (address)\\n {\\n return address(validatorManager);\\n }\\n\\n /// @notice returns address of dispute manager contract\\n function getDisputeManagerAddress() public view override returns (address) {\\n return address(disputeManager);\\n }\\n\\n /// @notice returns the current phase\\n function getCurrentPhase() public view returns (Phase) {\\n Phase currentPhase = Phase(storageVar.currentPhase_int);\\n return currentPhase;\\n }\\n\\n /// @notice returns the input accumulation start timestamp\\n function getInputAccumulationStart() public view returns (uint256) {\\n uint256 inputAccumulationStart = storageVar.inputAccumulationStart;\\n return inputAccumulationStart;\\n }\\n}\\n\",\"keccak256\":\"0x47afc7761a6c5312591927ef36469cfbf1caa36b33dc6fd010e699c94d8db4ba\",\"license\":\"Apache-2.0\"},\"contracts/ValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager\\npragma solidity >=0.7.0;\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface ValidatorManager {\\n // NoConflict - No conflicting claims or consensus\\n // Consensus - All validators had equal claims\\n // Conflict - Claim is conflicting with previous one\\n enum Result {NoConflict, Consensus, Conflict}\\n\\n // @notice called when a claim is received by rollups\\n // @params _sender address of sender of that claim\\n // @params _claim claim received by rollups\\n // @returns result of claim, signaling current state of claims\\n function onClaim(address payable _sender, bytes32 _claim)\\n external\\n returns (\\n Result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n );\\n\\n // @notice called when a dispute ends in rollups\\n // @params _winner address of dispute winner\\n // @params _loser address of dispute loser\\n // @returns result of dispute being finished\\n function onDisputeEnd(\\n address payable _winner,\\n address payable _loser,\\n bytes32 _winningClaim\\n )\\n external\\n returns (\\n Result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n );\\n\\n // @notice called when a new epoch starts\\n function onNewEpoch() external returns (bytes32);\\n\\n // @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n // @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n // @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n // @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0xd294eb8264d00d3c714ab8cbe058556d83f73089bc539ca5f48f095dd6e475f7\",\"license\":\"Apache-2.0\"},\"contracts/ValidatorManagerImpl.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager Implementation\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ValidatorManager.sol\\\";\\n\\ncontract ValidatorManagerImpl is ValidatorManager {\\n address immutable rollups; // rollups contract using this validator\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // current validators\\n\\n // A bit set for each validator that agrees with current claim,\\n // on their respective positions\\n uint32 claimAgreementMask;\\n\\n // Every validator who should approve (in order to reach consensus) will have a one set on this mask\\n // This mask is updated if a validator is added or removed\\n uint32 consensusGoalMask;\\n\\n // @notice functions modified by onlyRollups will only be executed if\\n // they're called by Rollups contract, otherwise it will throw an exception\\n function onlyRollups() internal view {\\n require(msg.sender == rollups, \\\"Only rollups\\\");\\n }\\n\\n // @notice populates validators array and creates a consensus mask\\n // @params _rollups address of rollupscontract\\n // @params _validators initial validator set\\n // @dev validators have to be unique, if the same validator is added twice\\n // consensus will never be reached\\n constructor(address _rollups, address payable[] memory _validators) {\\n rollups = _rollups;\\n validators = _validators;\\n\\n // create consensus goal, represents the scenario where all\\n // all validators claimed and agreed\\n consensusGoalMask = updateConsensusGoalMask();\\n }\\n\\n // @notice called when a claim is received by rollups\\n // @params _sender address of sender of that claim\\n // @params _claim claim received by rollups\\n // @return result of claim, Consensus | NoConflict | Conflict\\n // @return [currentClaim, conflicting claim] if there is Conflict\\n // [currentClaim, bytes32(0)] if there is Consensus\\n // [bytes32(0), bytes32(0)] if there is NoConflcit\\n // @return [claimer1, claimer2] if there is Conflcit\\n // [claimer1, address(0)] if there is Consensus\\n // [address(0), address(0)] if there is NoConflcit\\n function onClaim(address payable _sender, bytes32 _claim)\\n public\\n override\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n onlyRollups();\\n require(_claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(_sender), \\\"sender not allowed\\\");\\n\\n // cant return because a single claim might mean consensus\\n if (currentClaim == bytes32(0)) {\\n currentClaim = _claim;\\n }\\n\\n if (_claim != currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [currentClaim, _claim],\\n [getClaimerOfCurrentClaim(), _sender]\\n );\\n }\\n claimAgreementMask = updateClaimAgreementMask(_sender);\\n\\n return\\n isConsensus(claimAgreementMask, consensusGoalMask)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [_claim, bytes32(0)],\\n [_sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [bytes32(0), bytes32(0)],\\n [payable(0), payable(0)]\\n );\\n }\\n\\n // @notice called when a dispute ends in rollups\\n // @params _winner address of dispute winner\\n // @params _loser address of dispute loser\\n // @returns result of dispute being finished\\n function onDisputeEnd(\\n address payable _winner,\\n address payable _loser,\\n bytes32 _winningClaim\\n )\\n public\\n override\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n onlyRollups();\\n\\n // remove validator also removes validator from both bitmask\\n removeFromValidatorSetAndBothBitmasks(_loser);\\n\\n if (_winningClaim == currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(claimAgreementMask, consensusGoalMask)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [_winningClaim, bytes32(0)],\\n [_winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [bytes32(0), bytes32(0)],\\n [payable(0), payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (claimAgreementMask != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [currentClaim, _winningClaim],\\n [getClaimerOfCurrentClaim(), _winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n currentClaim = _winningClaim;\\n claimAgreementMask = updateClaimAgreementMask(_winner);\\n return\\n isConsensus(claimAgreementMask, consensusGoalMask)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [_winningClaim, bytes32(0)],\\n [_winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [bytes32(0), bytes32(0)],\\n [payable(0), payable(0)]\\n );\\n }\\n\\n // @notice called when a new epoch starts\\n // @return current claim\\n function onNewEpoch() public override returns (bytes32) {\\n onlyRollups();\\n\\n bytes32 tmpClaim = currentClaim;\\n\\n // clear current claim\\n currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n claimAgreementMask = 0;\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n // @notice get agreement mask\\n // @return current state of agreement mask\\n function getCurrentAgreementMask() public view returns (uint32) {\\n return claimAgreementMask;\\n }\\n\\n // @notice get consensus goal mask\\n // @return current consensus goal mask\\n function getConsensusGoalMask() public view returns (uint32) {\\n return consensusGoalMask;\\n }\\n\\n // @notice get current claim\\n // @return current claim\\n function getCurrentClaim() public view override returns (bytes32) {\\n return currentClaim;\\n }\\n\\n // INTERNAL FUNCTIONS\\n\\n // @notice emits dispute ended event and then return\\n // @param _result to be emitted and returned\\n // @param _claims to be emitted and returned\\n // @param _validators to be emitted and returned\\n // @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result _result,\\n bytes32[2] memory _claims,\\n address payable[2] memory _validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(_result, _claims, _validators);\\n return (_result, _claims, _validators);\\n }\\n\\n // @notice emits claim received event and then return\\n // @param _result to be emitted and returned\\n // @param _claims to be emitted and returned\\n // @param _validators to be emitted and returned\\n // @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result _result,\\n bytes32[2] memory _claims,\\n address payable[2] memory _validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(_result, _claims, _validators);\\n return (_result, _claims, _validators);\\n }\\n\\n // @notice get one of the validators that agreed with current claim\\n // @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim()\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n for (uint256 i; i < validators.length; i++) {\\n if (claimAgreementMask & (1 << i) != 0) {\\n return validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n // @notice updates the consensus goal mask\\n // @return new consensus goal mask\\n function updateConsensusGoalMask() internal view returns (uint32) {\\n // consensus goal is a number where\\n // all bits related to validators are turned on\\n uint256 consensusMask = (1 << validators.length) - 1;\\n return uint32(consensusMask);\\n }\\n\\n // @notice updates mask of validators that agreed with current claim\\n // @params _sender address that of validator that will be included in mask\\n // @return new claim agreement mask\\n function updateClaimAgreementMask(address payable _sender)\\n internal\\n view\\n returns (uint32)\\n {\\n uint256 tmpClaimAgreement = claimAgreementMask;\\n for (uint256 i; i < validators.length; i++) {\\n if (_sender == validators[i]) {\\n tmpClaimAgreement = (tmpClaimAgreement | (1 << i));\\n break;\\n }\\n }\\n\\n return uint32(tmpClaimAgreement);\\n }\\n\\n // @notice removes a validator\\n // @params address of validator to be removed\\n // @returns new claim agreement bitmask\\n // @returns new consensus goal bitmask\\n function removeFromValidatorSetAndBothBitmasks(address _validator)\\n internal\\n {\\n // put address(0) in validators position\\n // removes validator from claim agreement bitmask\\n // removes validator from consensus goal mask\\n for (uint256 i; i < validators.length; i++) {\\n if (_validator == validators[i]) {\\n validators[i] = payable(0);\\n uint32 zeroMask = ~(uint32(1) << uint32(i));\\n claimAgreementMask = claimAgreementMask & zeroMask;\\n consensusGoalMask = consensusGoalMask & zeroMask;\\n break;\\n }\\n }\\n }\\n\\n function isValidator(address _sender) internal view returns (bool) {\\n for (uint256 i; i < validators.length; i++) {\\n if (_sender == validators[i]) return true;\\n }\\n return false;\\n }\\n\\n function isConsensus(\\n uint256 _claimAgreementMask,\\n uint256 _consensusGoalMask\\n ) internal pure returns (bool) {\\n return _claimAgreementMask == _consensusGoalMask;\\n }\\n}\\n\",\"keccak256\":\"0x2fee6aa439d9419eb0d0da98db3d42b807aec7f9e66d2870278987d15ebc766a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162003b1538038062003b1583398101604081905262000034916200030f565b30826040516200004490620002a4565b6001600160a01b0390921682526020820152604001604051809103906000f08015801562000076573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b03929092169190911790556040513090620000a790620002b2565b6001600160a01b039091168152602001604051809103906000f080158015620000d4573d6000803e3d6000fd5b50600160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555030816040516200010b90620002c0565b6200011892919062000401565b604051809103906000f08015801562000135573d6000803e3d6000fd5b50600280546001600160a01b0319166001600160a01b039290921691909117905560405130906200016690620002ce565b6001600160a01b039091168152602001604051809103906000f08015801562000193573d6000803e3d6000fd5b50600380546001600160a01b0319166001600160a01b039283169081179091556040805160a0808201835263ffffffff898116808452898216602080860182905242909316858701819052600060608088018290526080978801829052600480546001600160401b03191690951764010000000090940293909317600160401b600160a01b03191668010000000000000000909202600160601b600160a01b0319169190911790925590546001546002548751928a168352908916938201939093529190961681850152948501939093528301879052908201859052517f0c34d7ca767e7f7b827de620cbd78c6291e2ca28d8ac112f26c5121912ea1ecc9181900360c00190a1505050506200045f565b61081e806200164183390190565b610d0f8062001e5f83390190565b610c7f8062002b6e83390190565b61032880620037ed83390190565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200030a57600080fd5b919050565b600080600080608085870312156200032657600080fd5b8451602080870151604088015160608901519397509095509350906001600160401b03808211156200035757600080fd5b818801915088601f8301126200036c57600080fd5b815181811115620003815762000381620002dc565b8060051b604051601f19603f83011681018181108582111715620003a957620003a9620002dc565b60405291825284820192508381018501918b831115620003c857600080fd5b938501935b82851015620003f157620003e185620002f2565b84529385019392850192620003cd565b989b979a50959850505050505050565b6001600160a01b038381168252604060208084018290528451918401829052600092858201929091906060860190855b818110156200045157855185168352948301949183019160010162000431565b509098975050505050505050565b6111d2806200046f6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063ddf7bcf011610097578063f20eaeb811610066578063f20eaeb81461025e578063f3cca85a14610271578063f544c3a614610282578063fe55bde91461029557600080fd5b8063ddf7bcf01461020d578063eaed3f4f14610222578063eaf5cb1a14610235578063eb71b0931461024657600080fd5b806382ae9ef7116100d357806382ae9ef7146101c7578063a3a40ea5146101cf578063b97dd9e2146101e4578063bd66528a146101fa57600080fd5b806321ae6567146101055780632cd007ed1461012f5780634ecfd8d6146101405780636c827cb114610155575b600080fd5b6002546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6001546001600160a01b0316610112565b61015361014e366004610f3b565b6102a8565b005b6004546101909063ffffffff808216916401000000008104821691600160401b8204811691600160601b8104821691600160801b9091041685565b6040805163ffffffff968716815294861660208601529285169284019290925283166060830152909116608082015260a001610126565b610153610423565b6101d76105f5565b6040516101269190610f92565b6101ec610621565b604051908152602001610126565b610153610208366004610fba565b610705565b600454600160401b900463ffffffff166101ec565b600054610112906001600160a01b031681565b6003546001600160a01b0316610112565b61024e6109ed565b6040519015158152602001610126565b600154610112906001600160a01b031681565b6000546001600160a01b0316610112565b600354610112906001600160a01b031681565b600254610112906001600160a01b031681565b6003546001600160a01b031633146102ff5760405162461bcd60e51b81526020600482015260156024820152741bdb9b1e48111a5cdc1d5d194810dbdb9d1c9858dd605a1b60448201526064015b60405180910390fd5b6000610309610f05565b610311610f05565b600254604051630d7dc39360e21b81526001600160a01b038881166004830152878116602483015260448201879052909116906335f70e4c9060640160a060405180830381600087803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039f919061100a565b6004805463ffffffff60601b1916600160601b4263ffffffff1602179055604080516001600160a01b03808c1682528a16602082015290810188905292955090935091507f2afbde4d47160a9c5de25b0df88d5b83e705286f2a447cac162db5e99ad6f5d29060600160405180910390a161041b838383610af7565b505050505050565b600454600090600160801b900463ffffffff16600281111561044757610447610f7c565b9050600181600281111561045d5761045d610f7c565b146104aa5760405162461bcd60e51b815260206004820152601b60248201527f506861736520213d204177616974696e6720436f6e73656e737573000000000060448201526064016102f6565b60045463ffffffff600160601b82048116916401000000009004166104cf81836110d8565b421161051d5760405162461bcd60e51b815260206004820152601960248201527f4368616c6c656e676520706572696f64206e6f74206f7665720000000000000060448201526064016102f6565b600254604080516320867f6960e21b815290516000926001600160a01b031691638219fda4916004808301926020929190829003018186803b15801561056257600080fd5b505afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906110fe565b14156105e85760405162461bcd60e51b815260206004820152601860248201527f4e6f20436c61696d20746f2062652066696e616c697a6564000000000000000060448201526064016102f6565b6105f0610c9d565b505050565b6004546000908190600160801b900463ffffffff16600281111561061b5761061b610f7c565b92915050565b600080600160009054906101000a90046001600160a01b03166001600160a01b03166383552b4d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561067257600080fd5b505afa158015610686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106aa91906110fe565b600454909150600090600160801b900463ffffffff1660028111156106d1576106d1610f7c565b905060008160028111156106e7576106e7610f7c565b146106fc576106f78260016110d8565b6106fe565b815b9250505090565b600061070f610f05565b610717610f05565b600454600090600160801b900463ffffffff16600281111561073b5761073b610f7c565b60045490915063ffffffff600160401b820481169116600083600281111561076557610765610f7c565b14801561077a575061077781836110d8565b42115b15610837576004805463ffffffff60801b1916600160801b1790556040516001935060008051602061117d833981519152906107b7908590610f92565b60405180910390a1600080546040805163851867b360e01b815290516001600160a01b039092169263851867b39260048084019382900301818387803b15801561080057600080fd5b505af1158015610814573d6000803e3d6000fd5b50506004805463ffffffff60601b1916600160601b4263ffffffff160217905550505b600183600281111561084b5761084b610f7c565b146108985760405162461bcd60e51b815260206004820152601a60248201527f506861736520213d204177616974696e67436f6e73656e73757300000000000060448201526064016102f6565b60025460405163fabc6a2960e01b8152336004820152602481018990526001600160a01b039091169063fabc6a299060440160a060405180830381600087803b1580156108e457600080fd5b505af11580156108f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091c919061100a565b600154604080516383552b4d60e01b81529051949a509298509096506001600160a01b0316916383552b4d91600480820192602092909190829003018186803b15801561096857600080fd5b505afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a091906110fe565b60408051338152602081018a90527fd31325e5dc55b03edf08c70299d3b1bc8d4c2ca8512c90138ddd03e3f54fce6c910160405180910390a26109e4868686610af7565b50505050505050565b600080546001600160a01b03163314610a3e5760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e48125b9c1d5d0810dbdb9d1c9858dd606a1b60448201526064016102f6565b600454600090600160801b900463ffffffff166002811115610a6257610a62610f7c565b60045490915063ffffffff600160401b8204811691166000836002811115610a8c57610a8c610f7c565b148015610aa15750610a9e81836110d8565b42115b15610aed576004805463ffffffff60801b1916600160801b17905560405160008051602061117d83398151915290610adb90600190610f92565b60405180910390a16001935050505090565b6000935050505090565b6000836002811115610b0b57610b0b610f7c565b1415610b9457600454600090600160801b900463ffffffff166002811115610b3557610b35610f7c565b90506001816002811115610b4b57610b4b610f7c565b14610b8e576004805463ffffffff60801b1916600160801b17905560405160008051602061117d83398151915290610b8590600190610f92565b60405180910390a15b50505050565b6001836002811115610ba857610ba8610f7c565b1415610bb6576105f0610c9d565b600454600090600160801b900463ffffffff166002811115610bda57610bda610f7c565b90506002816002811115610bf057610bf0610f7c565b14610c33576004805463ffffffff60801b1916600160811b17905560405160008051602061117d83398151915290610c2a90600290610f92565b60405180910390a15b600354604051632c83c47160e11b81526001600160a01b039091169063590788e290610c659086908690600401611117565b600060405180830381600087803b158015610c7f57600080fd5b505af1158015610c93573d6000803e3d6000fd5b5050505050505050565b6004805463ffffffff60801b1916905560405160008051602061117d83398151915290610ccc90600090610f92565b60405180910390a16004805463ffffffff60601b1963ffffffff4216600160401b02166fffffffffffffffff0000000000000000199091161763ffffffff60601b178155600254604080516379fa798360e01b815290516000936001600160a01b03909316926379fa79839280820192602092909182900301818787803b158015610d5657600080fd5b505af1158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e91906110fe565b9050600160009054906101000a90046001600160a01b03166001600160a01b03166383552b4d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dde57600080fd5b505afa158015610df2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1691906110fe565b6040518281527f6e3d05bc77b9307d9ba574c7c3196a746edd51104ded1c823edc63be4b8a63c39060200160405180910390a2600154604051638252b1dd60e01b8152600481018390526001600160a01b0390911690638252b1dd90602401600060405180830381600087803b158015610e8f57600080fd5b505af1158015610ea3573d6000803e3d6000fd5b505060008054604080516379fa798360e01b815290516001600160a01b0390921694506379fa79839350600480820193929182900301818387803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b5050505050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b0381168114610f3857600080fd5b50565b600080600060608486031215610f5057600080fd5b8335610f5b81610f23565b92506020840135610f6b81610f23565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b6020810160038310610fb457634e487b7160e01b600052602160045260246000fd5b91905290565b600060208284031215610fcc57600080fd5b5035919050565b6040805190810167ffffffffffffffff8111828210171561100457634e487b7160e01b600052604160045260246000fd5b60405290565b600080600060a0848603121561101f57600080fd5b83516003811061102e57600080fd5b92506020603f8501861361104157600080fd5b611049610fd3565b80606087018881111561105b57600080fd5b8388015b81811015611076578051845292840192840161105f565b5081955088607f89011261108957600080fd5b611091610fd3565b925082915060a08801898111156110a757600080fd5b808210156110c95781516110ba81610f23565b845292840192908401906110a7565b50508093505050509250925092565b600082198211156110f957634e487b7160e01b600052601160045260246000fd5b500190565b60006020828403121561111057600080fd5b5051919050565b60808101818460005b600281101561113f578151835260209283019290910190600101611120565b505050604082018360005b60028110156111725781516001600160a01b031683526020928301929091019060010161114a565b505050939250505056feed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8fa264697066735822122098e7f91abf8af465969726f09e88b1a8a2c53c88c140c40da2f40c312e0db84c64736f6c6343000809003360c060405234801561001057600080fd5b5060405161081e38038061081e83398101604081905261002f9161009e565b60038110158015610041575060408111155b6100845760405162461bcd60e51b815260206004820152601060248201526f6c6f672073697a653a205b332c36345d60801b604482015260640160405180910390fd5b6001600160a01b039091166080526001901b60a0526100d8565b600080604083850312156100b157600080fd5b82516001600160a01b03811681146100c857600080fd5b6020939093015192949293505050565b60805160a05161070c61011260003960006101720152600081816101e8015281816102a5015281816103ed01526104ce015261070c6000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80631ab6dcab1461006757806379fa79831461007d578063851867b314610087578063a459600e1461008f578063e7955244146100a2578063f32078e8146100aa575b600080fd5b6002545b60405190815260200160405180910390f35b6100856100bd565b005b6100856100e6565b61006b61009d366004610576565b6100f6565b61006b61014a565b61006b6100b836600461058f565b610164565b6100c56104c3565b600254156100da576100d8600080610544565b565b6100d860016000610544565b6100ee6104c3565b6100d861052a565b6000600254600014610125576000828154811061011557610115610601565b9060005260206000200154610144565b6001828154811061013857610138610601565b90600052602060002001545b92915050565b600060025460001461015d575060005490565b5060015490565b6000811580159061019557507f00000000000000000000000000000000000000000000000000000000000000008211155b6101e65760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a2028302c647269766553697a655d000000000000000060448201526064015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663eb71b0936040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561024157600080fd5b505af1158015610255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102799190610617565b156102865761028661052a565b600060025460001461029957600161029c565b60005b905060003343427f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b97dd9e26040518163ffffffff1660e01b815260040160206040518083038186803b1580156102fc57600080fd5b505afa158015610310573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103349190610640565b8554604080516001600160a01b0390961660208701528501939093526060840191909152608083015260a082015260c0016040516020818303038152906040528051906020012090506000858560405161038f929190610659565b6040805191829003822060208301859052908201819052915060009060600160408051601f1981840301815291905280516020918201208554600181810188556000888152939093200181905585549092506103eb9190610669565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b97dd9e26040518163ffffffff1660e01b815260040160206040518083038186803b15801561044457600080fd5b505afa158015610458573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047c9190610640565b7fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc733428b8b6040516104b1949392919061068e565b60405180910390a39695505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100d85760405162461bcd60e51b815260206004820152600c60248201526b4f6e6c7920726f6c6c75707360a01b60448201526064016101dd565b60025415610539576000600255565b600160028190555b50565b508054600082559060005260206000209081019061054191905b80821115610572576000815560010161055e565b5090565b60006020828403121561058857600080fd5b5035919050565b600080602083850312156105a257600080fd5b823567ffffffffffffffff808211156105ba57600080fd5b818501915085601f8301126105ce57600080fd5b8135818111156105dd57600080fd5b8660208285010111156105ef57600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561062957600080fd5b8151801515811461063957600080fd5b9392505050565b60006020828403121561065257600080fd5b5051919050565b8183823760009101908152919050565b60008282101561068957634e487b7160e01b600052601160045260246000fd5b500390565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f19160101939250505056fea2646970667358221220b1aa0e1533cd8db484ac6d6e5b46ccefe63aab5485d4e4f2bbf4449ca1be829a64736f6c6343000809003360a060405234801561001057600080fd5b50604051610d0f380380610d0f83398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b608051610c8461008b60003960006104780152610c846000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80638021be81116100715780638021be811461013e5780638252b1dd1461014557806383552b4d1461015a578063a238203614610162578063a981588a1461013e578063f3af7efd1461016257600080fd5b806310517cfc146100ae5780633ad58a27146100d35780633c0d9958146100f65780635e439a0c146101185780636190d81e1461012b575b600080fd5b6100c06100bc366004610876565b1b90565b6040519081526020015b60405180910390f35b6100e66100e13660046108c7565b610169565b60405190151581526020016100ca565b6100c06101043660046109a6565b608083901b604083901b1781179392505050565b6100e66101263660046108c7565b610187565b6100e66101393660046109d2565b61019d565b60156100c0565b610158610153366004610a88565b61046d565b005b6001546100c0565b60256100c0565b600061017f84848460a001356025601587610508565b949350505050565b600061017f848484608001356025601587610508565b60025460009060ff16156101f15760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b6002805460ff1916600117905560405160009061021690879087908790602001610aa1565b604051602081830303815290604052905061025381600185600001358154811061024257610242610ae1565b906000526020600020015485610187565b5060006020840135604090811b9085013560801b178435176040516303fbaf7360e01b81526000600482015260248101829052909150736Fc1eACde8ec4898711Ec3b03bbCc666361A136A906303fbaf739060440160206040518083038186803b1580156102c057600080fd5b505af41580156102d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f89190610af7565b156103455760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f776564000000000000000060448201526064016101e8565b6000876001600160a01b03168787604051610361929190610b20565b6000604051808303816000865af19150503d806000811461039e576040519150601f19603f3d011682016040523d82523d6000602084013e6103a3565b606091505b505090508015610458576040516306449da160e41b8152600060048201526024810183905260016044820152736Fc1eACde8ec4898711Ec3b03bbCc666361A136A90636449da109060640160006040518083038186803b15801561040657600080fd5b505af415801561041a573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc548260405161044f91815260200190565b60405180910390a15b6002805460ff19169055979650505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104d45760405162461bcd60e51b815260206004820152600c60248201526b4f6e6c7920726f6c6c75707360a01b60448201526064016101e8565b6001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60155565b60408051608080840135602083015260a08401359282019290925260c08301356060820152600091879101604051602081830303815290604052805190602001201461058c5760405162461bcd60e51b8152602060048201526013602482015272195c1bd8da12185cda081a5b98dbdc9c9958dd606a1b60448201526064016101e8565b8473DA9aafbDcda3a5DDFE0D1372ebd6201efE7F23246379de4601602085013560051b60058887606001356040516020016105c991815260200190565b60408051601f1981840301815291905280516020909101206105ef6101008a018a610b30565b6040518763ffffffff1660e01b815260040161061096959493929190610b81565b60206040518083038186803b15801561062857600080fd5b505af415801561063c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106609190610bd8565b146106ad5760405162461bcd60e51b815260206004820152601e60248201527f65706f63684f757470757444726976654861736820696e636f7272656374000060448201526064016101e8565b600073DA9aafbDcda3a5DDFE0D1372ebd6201efE7F232463c84583a189805190602001206040516020016106e391815260200190565b60405160208183030381529060405260056040518363ffffffff1660e01b8152600401610711929190610bf1565b60206040518083038186803b15801561072957600080fd5b505af415801561073d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107619190610bd8565b9050606083013573DA9aafbDcda3a5DDFE0D1372ebd6201efE7F23246379de4601604086013560051b6005888661079b60e08b018b610b30565b6040518763ffffffff1660e01b81526004016107bc96959493929190610b81565b60206040518083038186803b1580156107d457600080fd5b505af41580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190610bd8565b146108685760405162461bcd60e51b815260206004820152602660248201527f6f75747075744d65746164617461417272617944726976654861736820696e636044820152651bdc9c9958dd60d21b60648201526084016101e8565b506001979650505050505050565b6000806040838503121561088957600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600061012082840312156108c157600080fd5b50919050565b6000806000606084860312156108dc57600080fd5b833567ffffffffffffffff808211156108f457600080fd5b818601915086601f83011261090857600080fd5b81358181111561091a5761091a610898565b604051601f8201601f19908116603f0116810190838211818310171561094257610942610898565b8160405282815289602084870101111561095b57600080fd5b8260208601602083013760006020848301015280975050505060208601359350604086013591508082111561098f57600080fd5b5061099c868287016108ae565b9150509250925092565b6000806000606084860312156109bb57600080fd5b505081359360208301359350604090920135919050565b600080600080606085870312156109e857600080fd5b84356001600160a01b03811681146109ff57600080fd5b9350602085013567ffffffffffffffff80821115610a1c57600080fd5b818701915087601f830112610a3057600080fd5b813581811115610a3f57600080fd5b886020828501011115610a5157600080fd5b602083019550809450506040870135915080821115610a6f57600080fd5b50610a7c878288016108ae565b91505092959194509250565b600060208284031215610a9a57600080fd5b5035919050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610b0957600080fd5b81518015158114610b1957600080fd5b9392505050565b8183823760009101908152919050565b6000808335601e19843603018112610b4757600080fd5b83018035915067ffffffffffffffff821115610b6257600080fd5b6020019150600581901b3603821315610b7a57600080fd5b9250929050565b86815285602082015284604082015283606082015260a060808201528160a0820152600060018060fb1b03831115610bb857600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b600060208284031215610bea57600080fd5b5051919050565b604081526000835180604084015260005b81811015610c1f5760208187018101516060868401015201610c02565b81811115610c31576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fea26469706673582212207e7041ea77f3f912f78f0a06a2d971a7e3210272aff13d326deaf6d2d1fbb99564736f6c6343000809003360a06040523480156200001157600080fd5b5060405162000c7f38038062000c7f833981016040819052620000349162000169565b6001600160a01b038216608052805162000056906001906020840190620000a7565b506200006162000089565b600260046101000a81548163ffffffff021916908363ffffffff16021790555050506200027a565b600180546000918291620000a1919081901b62000254565b92915050565b828054828255906000526020600020908101928215620000ff579160200282015b82811115620000ff57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620000c8565b506200010d92915062000111565b5090565b5b808211156200010d576000815560010162000112565b6001600160a01b03811681146200013e57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620001648162000128565b919050565b600080604083850312156200017d57600080fd5b82516200018a8162000128565b602084810151919350906001600160401b0380821115620001aa57600080fd5b818601915086601f830112620001bf57600080fd5b815181811115620001d457620001d462000141565b8060051b604051601f19603f83011681018181108582111715620001fc57620001fc62000141565b6040529182528482019250838101850191898311156200021b57600080fd5b938501935b828510156200024457620002348562000157565b8452938501939285019262000220565b8096505050505050509250929050565b6000828210156200027557634e487b7160e01b600052601160045260246000fd5b500390565b6080516109e96200029660003960006104f601526109e96000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063012ad61c1461006757806335f70e4c1461008b57806379fa7983146100ad5780638219fda4146100c3578063f6023815146100cb578063fabc6a29146100e1575b600080fd5b60025463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b61009e610099366004610886565b6100f4565b604051610082939291906108c2565b6100b56102ce565b604051908152602001610082565b6000546100b5565b600254640100000000900463ffffffff16610071565b61009e6100ef36600461094a565b610324565b60006100fe61084c565b61010661084c565b61010e6104eb565b61011785610554565b6000548414156101b757600254640100000000810463ffffffff90811691161461017257604080518082018252600080825260208083018290528351808501909452818452830181905261016d9290919061062f565b6101ac565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526101ac916001919061062f565b9250925092506102c5565b60025463ffffffff161561020e576101ac6002604051806040016040528060005481526020018781525060405180604001604052806101f4610688565b6001600160a01b0390811682528b1660209091015261062f565b600084905561021c86610732565b6002805463ffffffff191663ffffffff928316908117918290556102499290916401000000009004161490565b61028457604080518082018252600080825260208083018290528351808501909452818452830181905261027f9290919061062f565b6102be565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526102be916001919061062f565b9250925092505b93509350939050565b60006102d86104eb565b600080549080556002805463ffffffff191690556040518181527fddc860800a99149017c480ec51523bf4143b7215e78956ae5c31e5c568f5383a9060200160405180910390a1919050565b600061032e61084c565b61033661084c565b61033e6104eb565b8361037e5760405162461bcd60e51b815260206004820152600b60248201526a656d70747920636c61696d60a81b60448201526064015b60405180910390fd5b610387856107a3565b6103c85760405162461bcd60e51b81526020600482015260126024820152711cd95b99195c881b9bdd08185b1b1bddd95960721b6044820152606401610375565b6000546103d55760008490555b60005484146104325761042760026040518060400160405280600054815260200187815250604051806040016040528061040d610688565b6001600160a01b0390811682528a16602090910152610807565b9250925092506104e4565b61043b85610732565b6002805463ffffffff191663ffffffff928316908117918290556104689290916401000000009004161490565b6104a357604080518082018252600080825260208083018290528351808501909452818452830181905261049e92909190610807565b6104dd565b6040805180820182528581526000602080830182905283518085019094526001600160a01b03891684528301526104dd9160019190610807565b9250925092505b9250925092565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105525760405162461bcd60e51b815260206004820152600c60248201526b4f6e6c7920726f6c6c75707360a01b6044820152606401610375565b565b60005b60015481101561062b576001818154811061057457610574610974565b6000918252602090912001546001600160a01b0383811691161415610619576000600182815481106105a8576105a8610974565b600091825260209091200180546001600160a01b03929092166001600160a01b03199092169190911790556002805464010000000063ffffffff198216600163ffffffff8087169190911b198481168216928317849004161690910267ffffffffffffffff19909216171790555050565b806106238161098a565b915050610557565b5050565b600061063961084c565b61064161084c565b7f09201c193a07cae1df95ae692cc698685574c942a04514c48a4c3249f38594ff868686604051610674939291906108c2565b60405180910390a150939492935090919050565b6000805b6001548110156106e9576002546001821b1663ffffffff16156106d757600181815481106106bc576106bc610974565b6000918252602090912001546001600160a01b031692915050565b806106e18161098a565b91505061068c565b5060405162461bcd60e51b815260206004820152601c60248201527f4167726565696e672076616c696461746f72206e6f7420666f756e64000000006044820152606401610375565b60025460009063ffffffff16815b60015481101561079c576001818154811061075d5761075d610974565b6000918252602090912001546001600160a01b038581169116141561078a57806001901b8217915061079c565b806107948161098a565b915050610740565b5092915050565b6000805b6001548110156107fe57600181815481106107c4576107c4610974565b6000918252602090912001546001600160a01b03848116911614156107ec5750600192915050565b806107f68161098a565b9150506107a7565b50600092915050565b600061081161084c565b61081961084c565b7f495383aed97965c56495cdbadedfe9667a1b028c54d3fc4b5335895146e02b70868686604051610674939291906108c2565b60405180604001604052806002906020820280368337509192915050565b80356001600160a01b038116811461088157600080fd5b919050565b60008060006060848603121561089b57600080fd5b6108a48461086a565b92506108b26020850161086a565b9150604084013590509250925092565b60a08101600385106108e457634e487b7160e01b600052602160045260246000fd5b84825260208083018560005b600281101561090d578151835291830191908301906001016108f0565b505050606083018460005b600281101561093e5781516001600160a01b031683529183019190830190600101610918565b50505050949350505050565b6000806040838503121561095d57600080fd5b6109668361086a565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b60006000198214156109ac57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220307d873058c34130048a9909f469a9bc90b3eed5d8037ef76f5dab36284f5eb064736f6c6343000809003360a060405234801561001057600080fd5b5060405161032838038061032883398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b608051610297610091600039600081816050015261010201526102976000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063590788e214610030575b600080fd5b61004361003e36600461019b565b610045565b005b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100cd5760405162461bcd60e51b8152602060048201526024808201527f4f6e6c7920726f6c6c7570732063616e2063616c6c20746869732066756e6374604482015263696f6e7360e01b606482015260840160405180910390fd5b805160208201518351604051632767ec6b60e11b81526001600160a01b039384166004820152918316602483015260448201527f000000000000000000000000000000000000000000000000000000000000000090911690634ecfd8d690606401600060405180830381600087803b15801561014857600080fd5b505af115801561015c573d6000803e3d6000fd5b505050505050565b6040805190810167ffffffffffffffff8111828210171561019557634e487b7160e01b600052604160045260246000fd5b60405290565b600080608083850312156101ae57600080fd5b83601f8401126101bd57600080fd5b6101c5610164565b8060408501868111156101d757600080fd5b855b818110156101f15780358452602093840193016101d9565b5081945086605f87011261020457600080fd5b61020c610164565b9250829150608086018781111561022257600080fd5b808210156102545781356001600160a01b03811681146102425760008081fd5b84526020938401939190910190610222565b509396909550935050505056fea26469706673582212200a0bc85bbb603e01e12e026e73b6a114fe768b0bb0d7f9de9837eb39ee08c2c664736f6c63430008090033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c8063ddf7bcf011610097578063f20eaeb811610066578063f20eaeb81461025e578063f3cca85a14610271578063f544c3a614610282578063fe55bde91461029557600080fd5b8063ddf7bcf01461020d578063eaed3f4f14610222578063eaf5cb1a14610235578063eb71b0931461024657600080fd5b806382ae9ef7116100d357806382ae9ef7146101c7578063a3a40ea5146101cf578063b97dd9e2146101e4578063bd66528a146101fa57600080fd5b806321ae6567146101055780632cd007ed1461012f5780634ecfd8d6146101405780636c827cb114610155575b600080fd5b6002546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6001546001600160a01b0316610112565b61015361014e366004610f3b565b6102a8565b005b6004546101909063ffffffff808216916401000000008104821691600160401b8204811691600160601b8104821691600160801b9091041685565b6040805163ffffffff968716815294861660208601529285169284019290925283166060830152909116608082015260a001610126565b610153610423565b6101d76105f5565b6040516101269190610f92565b6101ec610621565b604051908152602001610126565b610153610208366004610fba565b610705565b600454600160401b900463ffffffff166101ec565b600054610112906001600160a01b031681565b6003546001600160a01b0316610112565b61024e6109ed565b6040519015158152602001610126565b600154610112906001600160a01b031681565b6000546001600160a01b0316610112565b600354610112906001600160a01b031681565b600254610112906001600160a01b031681565b6003546001600160a01b031633146102ff5760405162461bcd60e51b81526020600482015260156024820152741bdb9b1e48111a5cdc1d5d194810dbdb9d1c9858dd605a1b60448201526064015b60405180910390fd5b6000610309610f05565b610311610f05565b600254604051630d7dc39360e21b81526001600160a01b038881166004830152878116602483015260448201879052909116906335f70e4c9060640160a060405180830381600087803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039f919061100a565b6004805463ffffffff60601b1916600160601b4263ffffffff1602179055604080516001600160a01b03808c1682528a16602082015290810188905292955090935091507f2afbde4d47160a9c5de25b0df88d5b83e705286f2a447cac162db5e99ad6f5d29060600160405180910390a161041b838383610af7565b505050505050565b600454600090600160801b900463ffffffff16600281111561044757610447610f7c565b9050600181600281111561045d5761045d610f7c565b146104aa5760405162461bcd60e51b815260206004820152601b60248201527f506861736520213d204177616974696e6720436f6e73656e737573000000000060448201526064016102f6565b60045463ffffffff600160601b82048116916401000000009004166104cf81836110d8565b421161051d5760405162461bcd60e51b815260206004820152601960248201527f4368616c6c656e676520706572696f64206e6f74206f7665720000000000000060448201526064016102f6565b600254604080516320867f6960e21b815290516000926001600160a01b031691638219fda4916004808301926020929190829003018186803b15801561056257600080fd5b505afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906110fe565b14156105e85760405162461bcd60e51b815260206004820152601860248201527f4e6f20436c61696d20746f2062652066696e616c697a6564000000000000000060448201526064016102f6565b6105f0610c9d565b505050565b6004546000908190600160801b900463ffffffff16600281111561061b5761061b610f7c565b92915050565b600080600160009054906101000a90046001600160a01b03166001600160a01b03166383552b4d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561067257600080fd5b505afa158015610686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106aa91906110fe565b600454909150600090600160801b900463ffffffff1660028111156106d1576106d1610f7c565b905060008160028111156106e7576106e7610f7c565b146106fc576106f78260016110d8565b6106fe565b815b9250505090565b600061070f610f05565b610717610f05565b600454600090600160801b900463ffffffff16600281111561073b5761073b610f7c565b60045490915063ffffffff600160401b820481169116600083600281111561076557610765610f7c565b14801561077a575061077781836110d8565b42115b15610837576004805463ffffffff60801b1916600160801b1790556040516001935060008051602061117d833981519152906107b7908590610f92565b60405180910390a1600080546040805163851867b360e01b815290516001600160a01b039092169263851867b39260048084019382900301818387803b15801561080057600080fd5b505af1158015610814573d6000803e3d6000fd5b50506004805463ffffffff60601b1916600160601b4263ffffffff160217905550505b600183600281111561084b5761084b610f7c565b146108985760405162461bcd60e51b815260206004820152601a60248201527f506861736520213d204177616974696e67436f6e73656e73757300000000000060448201526064016102f6565b60025460405163fabc6a2960e01b8152336004820152602481018990526001600160a01b039091169063fabc6a299060440160a060405180830381600087803b1580156108e457600080fd5b505af11580156108f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091c919061100a565b600154604080516383552b4d60e01b81529051949a509298509096506001600160a01b0316916383552b4d91600480820192602092909190829003018186803b15801561096857600080fd5b505afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a091906110fe565b60408051338152602081018a90527fd31325e5dc55b03edf08c70299d3b1bc8d4c2ca8512c90138ddd03e3f54fce6c910160405180910390a26109e4868686610af7565b50505050505050565b600080546001600160a01b03163314610a3e5760405162461bcd60e51b81526020600482015260136024820152721bdb9b1e48125b9c1d5d0810dbdb9d1c9858dd606a1b60448201526064016102f6565b600454600090600160801b900463ffffffff166002811115610a6257610a62610f7c565b60045490915063ffffffff600160401b8204811691166000836002811115610a8c57610a8c610f7c565b148015610aa15750610a9e81836110d8565b42115b15610aed576004805463ffffffff60801b1916600160801b17905560405160008051602061117d83398151915290610adb90600190610f92565b60405180910390a16001935050505090565b6000935050505090565b6000836002811115610b0b57610b0b610f7c565b1415610b9457600454600090600160801b900463ffffffff166002811115610b3557610b35610f7c565b90506001816002811115610b4b57610b4b610f7c565b14610b8e576004805463ffffffff60801b1916600160801b17905560405160008051602061117d83398151915290610b8590600190610f92565b60405180910390a15b50505050565b6001836002811115610ba857610ba8610f7c565b1415610bb6576105f0610c9d565b600454600090600160801b900463ffffffff166002811115610bda57610bda610f7c565b90506002816002811115610bf057610bf0610f7c565b14610c33576004805463ffffffff60801b1916600160811b17905560405160008051602061117d83398151915290610c2a90600290610f92565b60405180910390a15b600354604051632c83c47160e11b81526001600160a01b039091169063590788e290610c659086908690600401611117565b600060405180830381600087803b158015610c7f57600080fd5b505af1158015610c93573d6000803e3d6000fd5b5050505050505050565b6004805463ffffffff60801b1916905560405160008051602061117d83398151915290610ccc90600090610f92565b60405180910390a16004805463ffffffff60601b1963ffffffff4216600160401b02166fffffffffffffffff0000000000000000199091161763ffffffff60601b178155600254604080516379fa798360e01b815290516000936001600160a01b03909316926379fa79839280820192602092909182900301818787803b158015610d5657600080fd5b505af1158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e91906110fe565b9050600160009054906101000a90046001600160a01b03166001600160a01b03166383552b4d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dde57600080fd5b505afa158015610df2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1691906110fe565b6040518281527f6e3d05bc77b9307d9ba574c7c3196a746edd51104ded1c823edc63be4b8a63c39060200160405180910390a2600154604051638252b1dd60e01b8152600481018390526001600160a01b0390911690638252b1dd90602401600060405180830381600087803b158015610e8f57600080fd5b505af1158015610ea3573d6000803e3d6000fd5b505060008054604080516379fa798360e01b815290516001600160a01b0390921694506379fa79839350600480820193929182900301818387803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b5050505050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b0381168114610f3857600080fd5b50565b600080600060608486031215610f5057600080fd5b8335610f5b81610f23565b92506020840135610f6b81610f23565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b6020810160038310610fb457634e487b7160e01b600052602160045260246000fd5b91905290565b600060208284031215610fcc57600080fd5b5035919050565b6040805190810167ffffffffffffffff8111828210171561100457634e487b7160e01b600052604160045260246000fd5b60405290565b600080600060a0848603121561101f57600080fd5b83516003811061102e57600080fd5b92506020603f8501861361104157600080fd5b611049610fd3565b80606087018881111561105b57600080fd5b8388015b81811015611076578051845292840192840161105f565b5081955088607f89011261108957600080fd5b611091610fd3565b925082915060a08801898111156110a757600080fd5b808210156110c95781516110ba81610f23565b845292840192908401906110a7565b50508093505050509250925092565b600082198211156110f957634e487b7160e01b600052601160045260246000fd5b500190565b60006020828403121561111057600080fd5b5051919050565b60808101818460005b600281101561113f578151835260209283019290910190600101611120565b505050604082018360005b60028110156111725781516001600160a01b031683526020928301929091019060010161114a565b505050939250505056feed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8fa264697066735822122098e7f91abf8af465969726f09e88b1a8a2c53c88c140c40da2f40c312e0db84c64736f6c63430008090033", + "libraries": { + "Bitmask": "0x6Fc1eACde8ec4898711Ec3b03bbCc666361A136A", + "Merkle": "0xDA9aafbDcda3a5DDFE0D1372ebd6201efE7F2324" + }, + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_challengePeriod": "duration of challenge period in seconds", + "_inputDuration": "duration of input accumulation phase in seconds", + "_inputLog2Size": "size of the input drive in this machine", + "_validators": "initial validator set" + } + }, + "finalizeEpoch()": { + "details": "can only be called if challenge period is over" + }, + "getCurrentEpoch()": { + "details": "if phase is input accumulation, then the epoch number is length", + "returns": { + "_0": "index of current epoch" + } + }, + "notifyInput()": { + "details": "can only be called by input contract" + }, + "resolveDispute(address,address,bytes32)": { + "details": "can only be called by the dispute contract", + "params": { + "_loser": "loser of dispute", + "_winner": "winner of dispute", + "_winningClaim": "initial claim of winning validator" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "Claim(uint256,address,bytes32)": { + "notice": "claim submitted" + }, + "FinalizeEpoch(uint256,bytes32)": { + "notice": "epoch finalized" + }, + "PhaseChange(uint8)": { + "notice": "phase change" + }, + "ResolveDispute(address,address,bytes32)": { + "notice": "dispute resolved" + }, + "RollupsCreated(address,address,address,address,uint256,uint256)": { + "notice": "contract created" + } + }, + "kind": "user", + "methods": { + "claim(bytes32)": { + "notice": "TODO: add signatures for aggregated claims" + }, + "constructor": { + "notice": "creates contract" + }, + "finalizeEpoch()": { + "notice": "finalize epoch after timeout" + }, + "getCurrentEpoch()": { + "notice": "returns index of current (accumulating) epoch" + }, + "getCurrentPhase()": { + "notice": "returns the current phase" + }, + "getDisputeManagerAddress()": { + "notice": "returns address of dispute manager contract" + }, + "getInputAccumulationStart()": { + "notice": "returns the input accumulation start timestamp" + }, + "getInputAddress()": { + "notice": "returns address of input contract" + }, + "getOutputAddress()": { + "notice": "returns address of output contract" + }, + "getValidatorManagerAddress()": { + "notice": "returns address of validator manager contract" + }, + "notifyInput()": { + "notice": "called when new input arrives, manages the phase changes" + }, + "resolveDispute(address,address,bytes32)": { + "notice": "called when a dispute is resolved by the dispute manager" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3838, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "input", + "offset": 0, + "slot": "0", + "type": "t_contract(InputImpl)3221" + }, + { + "astId": 3841, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "output", + "offset": 0, + "slot": "1", + "type": "t_contract(OutputImpl)3714" + }, + { + "astId": 3844, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "validatorManager", + "offset": 0, + "slot": "2", + "type": "t_contract(ValidatorManagerImpl)6421" + }, + { + "astId": 3847, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "disputeManager", + "offset": 0, + "slot": "3", + "type": "t_contract(DisputeManagerImpl)2227" + }, + { + "astId": 3861, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "storageVar", + "offset": 0, + "slot": "4", + "type": "t_struct(StorageVar)3858_storage" + } + ], + "types": { + "t_contract(DisputeManagerImpl)2227": { + "encoding": "inplace", + "label": "contract DisputeManagerImpl", + "numberOfBytes": "20" + }, + "t_contract(InputImpl)3221": { + "encoding": "inplace", + "label": "contract InputImpl", + "numberOfBytes": "20" + }, + "t_contract(OutputImpl)3714": { + "encoding": "inplace", + "label": "contract OutputImpl", + "numberOfBytes": "20" + }, + "t_contract(ValidatorManagerImpl)6421": { + "encoding": "inplace", + "label": "contract ValidatorManagerImpl", + "numberOfBytes": "20" + }, + "t_struct(StorageVar)3858_storage": { + "encoding": "inplace", + "label": "struct RollupsImpl.StorageVar", + "members": [ + { + "astId": 3849, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "inputDuration", + "offset": 0, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 3851, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "challengePeriod", + "offset": 4, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 3853, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "inputAccumulationStart", + "offset": 8, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 3855, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "sealingEpochTimestamp", + "offset": 12, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 3857, + "contract": "contracts/RollupsImpl.sol:RollupsImpl", + "label": "currentPhase_int", + "offset": 16, + "slot": "0", + "type": "t_uint32" + } + ], + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/php-basic-crud/contracts/export/abi/polygon_mumbai.json b/php-basic-crud/contracts/export/abi/polygon_mumbai.json new file mode 100644 index 00000000..3744f00f --- /dev/null +++ b/php-basic-crud/contracts/export/abi/polygon_mumbai.json @@ -0,0 +1,1735 @@ +{ + "name": "polygon_mumbai", + "chainId": "80001", + "contracts": { + "ERC20PortalImpl": { + "address": "0x485155F7241c851fc7e7F0c58AD43E4FBA5852e2", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_inputContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_outputContract", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "ERC20Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "indexed": false, + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ERC20Withdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "erc20Deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "executeRollupsVoucher", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "EtherPortalImpl": { + "address": "0x794E1A83C525ecF06Cd7f33297368A3dbf3e7e8A", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_inputContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_outputContract", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "EtherDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "EtherWithdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "etherDeposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "executeRollupsVoucher", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "RollupsImpl": { + "address": "0x2DE3edbcF55a1FAC46c665Bb8C0Fd95FB353deEa", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_inputDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_challengePeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_inputLog2Size", + "type": "uint256" + }, + { + "internalType": "address payable[]", + "name": "_validators", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_claimer", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "FinalizeEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Rollups.Phase", + "name": "_newPhase", + "type": "uint8" + } + ], + "name": "PhaseChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_winner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_loser", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_winningClaim", + "type": "bytes32" + } + ], + "name": "ResolveDispute", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_input", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_output", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_validatorManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_disputeManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_inputDuration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_challengePeriod", + "type": "uint256" + } + ], + "name": "RollupsCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disputeManager", + "outputs": [ + { + "internalType": "contract DisputeManagerImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "finalizeEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentPhase", + "outputs": [ + { + "internalType": "enum Rollups.Phase", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDisputeManagerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputAccumulationStart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOutputAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorManagerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "input", + "outputs": [ + { + "internalType": "contract InputImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "notifyInput", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "output", + "outputs": [ + { + "internalType": "contract OutputImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_winner", + "type": "address" + }, + { + "internalType": "address payable", + "name": "_loser", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_winningClaim", + "type": "bytes32" + } + ], + "name": "resolveDispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "storageVar", + "outputs": [ + { + "internalType": "uint32", + "name": "inputDuration", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "challengePeriod", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "inputAccumulationStart", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "sealingEpochTimestamp", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "currentPhase_int", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validatorManager", + "outputs": [ + { + "internalType": "contract ValidatorManagerImpl", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "Bitmask": { + "address": "0x6Fc1eACde8ec4898711Ec3b03bbCc666361A136A", + "abi": [] + }, + "BitsManipulation": { + "address": "0xa5e4CbdF1767f0406ec5dee4aDb8125F4a637C64", + "abi": [ + { + "inputs": [ + { + "internalType": "int32", + "name": "number", + "type": "int32" + }, + { + "internalType": "uint32", + "name": "wordSize", + "type": "uint32" + } + ], + "name": "int32SignExtension", + "outputs": [ + { + "internalType": "int32", + "name": "", + "type": "int32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "num", + "type": "uint32" + } + ], + "name": "uint32SwapEndian", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "number", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "wordSize", + "type": "uint64" + } + ], + "name": "uint64SignExtension", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "num", + "type": "uint64" + } + ], + "name": "uint64SwapEndian", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + } + ] + }, + "CartesiMath": { + "address": "0x3f8B458Dd717DE4c625b227eD2f62c1DB2589BF0", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "clz", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "ctz", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "getLog2Floor", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "getLog2TableTimes1M", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "isPowerOf2", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "log2ApproxTimes1M", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ] + }, + "Merkle": { + "address": "0xDA9aafbDcda3a5DDFE0D1372ebd6201efE7F2324", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "hashes", + "type": "bytes32[]" + } + ], + "name": "calculateRootFromPowerOfTwo", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getEmptyTreeHashAtIndex", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_wordIndex", + "type": "uint256" + } + ], + "name": "getHashOfWordAtIndex", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_log2Size", + "type": "uint256" + } + ], + "name": "getMerkleRootFromBytes", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_position", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_logSizeOfReplacement", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_logSizeOfFullDrive", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_replacement", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "siblings", + "type": "bytes32[]" + } + ], + "name": "getRootAfterReplacementInDrive", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + } + ] + }, + "WorkerAuthManagerImpl": { + "address": "0x7A488CCc689D8596fcdd599868Df8053806EE60e", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_workerManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Authorization", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Deauthorization", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "authorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "deauthorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "isAuthorized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "WorkerManagerAuthManagerImpl": { + "address": "0x2c3C02219dc8be4E63e357467f1Ba8Ac77c5bfdb", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Authorization", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Deauthorization", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobOffer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobRejected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "Retired", + "type": "event" + }, + { + "inputs": [], + "name": "acceptJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "authorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "cancelHire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "deauthorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getUser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "hire", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "hireAndAuthorize", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "isAuthorized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isAvailable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isOwned", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isPending", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isRetired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rejectJob", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "retire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "WorkerManagerImpl": { + "address": "0x02dABCbC3886A72b39C3Ea88F8979B66F56b892B", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobOffer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobRejected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "Retired", + "type": "event" + }, + { + "inputs": [], + "name": "acceptJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "cancelHire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getUser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "hire", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isAvailable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isOwned", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isPending", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isRetired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rejectJob", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "retire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + } + } +} \ No newline at end of file diff --git a/php-basic-crud/contracts/hardhat.config.ts b/php-basic-crud/contracts/hardhat.config.ts new file mode 100644 index 00000000..6bb1d40b --- /dev/null +++ b/php-basic-crud/contracts/hardhat.config.ts @@ -0,0 +1,106 @@ +// Copyright 2022 Cartesi Pte. Ltd. + +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the license at http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +import { HardhatUserConfig } from "hardhat/config"; +import { HttpNetworkUserConfig } from "hardhat/types"; + +import "@nomiclabs/hardhat-waffle"; +import "@nomiclabs/hardhat-ethers"; +import "@nomiclabs/hardhat-etherscan"; +import "@typechain/hardhat"; +import "hardhat-deploy"; +import "@cartesi/rollups"; +import { appTasks } from "@cartesi/rollups"; + +// get app name +import { name } from "./package.json"; + +// define app tasks that calls rollups tasks, resolving rollups contract address +// i.e. php-basic-crud:addInput -> rollups:addInput +appTasks(name); + +// read MNEMONIC from file or from env variable +let mnemonic = process.env.MNEMONIC; + +const infuraNetwork = ( + network: string, + chainId?: number, + gas?: number +): HttpNetworkUserConfig => { + return { + url: `https://${network}.infura.io/v3/${process.env.PROJECT_ID}`, + chainId, + gas, + accounts: mnemonic ? { mnemonic } : undefined, + }; +}; + +const config: HardhatUserConfig = { + networks: { + hardhat: mnemonic ? { accounts: { mnemonic } } : {}, + localhost: { + url: "http://localhost:8545", + accounts: mnemonic ? { mnemonic } : undefined, + }, + ropsten: infuraNetwork("ropsten", 3, 6283185), + rinkeby: infuraNetwork("rinkeby", 4, 6283185), + kovan: infuraNetwork("kovan", 42, 6283185), + goerli: infuraNetwork("goerli", 5, 6283185), + mainnet: infuraNetwork("mainnet", 1, 6283185), + polygon_mumbai: infuraNetwork("polygon-mumbai", 80001), + bsc_testnet: { + url: "https://data-seed-prebsc-1-s1.binance.org:8545", + chainId: 97, + accounts: mnemonic ? { mnemonic } : undefined, + }, + }, + external: { + contracts: [ + { + artifacts: "node_modules/@cartesi/util/export/artifacts", + deploy: "node_modules/@cartesi/util/dist/deploy", + }, + { + artifacts: "node_modules/@cartesi/rollups/export/artifacts", + }, + ], + deployments: { + localhost: ["node_modules/@cartesi/util/deployments/localhost"], + mainnet: ["node_modules/@cartesi/util/deployments/mainnet"], + ropsten: ["node_modules/@cartesi/util/deployments/ropsten"], + rinkeby: ["node_modules/@cartesi/util/deployments/rinkeby"], + kovan: ["node_modules/@cartesi/util/deployments/kovan"], + goerli: ["node_modules/@cartesi/util/deployments/goerli"], + polygon_mumbai: [ + "node_modules/@cartesi/util/deployments/matic_testnet", + ], + bsc_testnet: ["node_modules/@cartesi/util/deployments/bsc_testnet"], + }, + }, + etherscan: { + apiKey: { + polygonMumbai: process.env.ETHERSCAN_API_KEY_POLYGON, + }, + }, + verify: { + etherscan: { + apiKey: process.env.ETHERSCAN_API_KEY, + }, + }, + namedAccounts: { + deployer: { + default: 0, + }, + }, +}; + +export default config; diff --git a/php-basic-crud/contracts/package.json b/php-basic-crud/contracts/package.json new file mode 100644 index 00000000..3f5de1d6 --- /dev/null +++ b/php-basic-crud/contracts/package.json @@ -0,0 +1,92 @@ +{ + "name": "php-basic-crud", + "version": "0.2.1", + "description": "PHP Basic Crud DApp", + "main": "index.ts", + "license": "Apache-2.0", + "scripts": { + "build": "run-s compile", + "clean:ignored": "rimraf artifacts && rimraf cache && rimraf coverage && rimraf deployments/localhost && rimraf dist && rimraf src/types/* && rimraf generated-src", + "clean:hardhat": "hardhat clean", + "clean": "run-s clean:hardhat clean:ignored", + "compile": "hardhat compile", + "copy-dts": "copyfiles -u 1 \"src/**/*.d.ts\" dist/src", + "deploy": "hardhat deploy", + "deploy:bsc_testnet": "hardhat deploy --network bsc_testnet --export export/abi/bsc_testnet.json", + "deploy:development": "hardhat deploy --network localhost", + "deploy:goerli": "hardhat deploy --network goerli --export export/abi/goerli.json", + "deploy:kovan": "hardhat deploy --network kovan --export export/abi/kovan.json", + "deploy:mainnet": "hardhat deploy --network mainnet --export export/abi/mainnet.json", + "deploy:polygon_mumbai": "hardhat deploy --network polygon_mumbai --export export/abi/polygon_mumbai.json", + "deploy:rinkeby": "hardhat deploy --network rinkeby --export export/abi/rinkeby.json", + "deploy:ropsten": "hardhat deploy --network ropsten --export export/abi/ropsten.json", + "deploy:testnet": "run-s deploy:rinkeby deploy:ropsten deploy:kovan deploy:goerli deploy:polygon_mumbai deploy:bsc_testnet", + "export": "hardhat export-artifacts export/artifacts", + "info": "npm-scripts-info", + "prepack": "run-s export tsc copy-dts", + "prettier": "prettier --check src/**/*.ts test/**/*.ts contracts/**/*.sol", + "solhint": "solhint contracts/**/*.sol", + "start": "hardhat node", + "test": "hardhat test", + "test:coverage": "hardhat coverage", + "tsc": "tsc" + }, + "scripts-info": { + "build": "Build contracts and typescript code", + "clean": "Clean build artifacts, including contracts local deployment information", + "copy-dts": "Copy TypeChain type definition files to typescript output dir", + "deploy": "Deploy contracts hardhat node, just for testing deploy scripts", + "deploy:bsc_testnet": "Deploy contracts to bsc_testnet.", + "deploy:development": "Deploy contracts to local node. Requires node running on localhost:8545", + "deploy:goerli": "Deploy contracts to goerli. Requires two environment variables: PROJECT_ID and MNEMONIC.", + "deploy:kovan": "Deploy contracts to kovan. Requires two environment variables: PROJECT_ID and MNEMONIC.", + "deploy:mainnet": "Deploy contracts to mainnet.", + "deploy:polygon_mumbai": "Deploy contracts to polygon_mumbai.", + "deploy:rinkeby": "Deploy contracts to rinkeby. Requires two environment variables: PROJECT_ID and MNEMONIC.", + "deploy:ropsten": "Deploy contracts to ropsten. Requires two environment variables: PROJECT_ID and MNEMONIC.", + "deploy:testnet": "Deploy contracts to all supported testnets. Requires two environment variables: PROJECT_ID and MNEMONIC.", + "export": "Export artifacts in a simpler format", + "info": "Displays information about the scripts.", + "prettier": "Check code style", + "solhint": "Run solidity linter", + "start": "Start hardhat node server", + "test": "Run unit tests", + "test:coverage": "Run test coverage report" + }, + "devDependencies": { + "@cartesi/rollups": "^0.1.1", + "@nomiclabs/hardhat-ethers": "^2.0.3", + "@nomiclabs/hardhat-etherscan": "^3.0.0", + "@nomiclabs/hardhat-waffle": "^2.0.1", + "@typechain/ethers-v5": "^8.0.5", + "@typechain/hardhat": "^3.1.0", + "@types/mocha": "^9.0.0", + "@types/node": "^17.0.8", + "copyfiles": "^2.4.1", + "cosmiconfig": "^7.0.1", + "ethereum-waffle": "^3.4.0", + "ethers": "^5.5.2", + "hardhat": "^2.8.0", + "hardhat-deploy": "^0.10.0", + "npm-run-all": "^4.1.5", + "npm-scripts-info": "^0.3.9", + "prettier": "^2.5.1", + "prettier-plugin-solidity": "^1.0.0-beta.19", + "rimraf": "^3.0.2", + "solhint": "^3.3.6", + "solhint-plugin-prettier": "^0.0.5", + "solidity-coverage": "^0.7.17", + "ts-node": "^10.4.0", + "typechain": "^6.1.0", + "typescript": "^4.5.4" + }, + "files": [ + "contracts", + "deployments/*/*.json", + "deployments/*/.chainid", + "dist/src/types", + "dist/deploy/*.js", + "export", + "!export/abi/localhost.json" + ] +} diff --git a/php-basic-crud/contracts/tsconfig.json b/php-basic-crud/contracts/tsconfig.json new file mode 100644 index 00000000..8155b749 --- /dev/null +++ b/php-basic-crud/contracts/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "declaration": true, + "target": "es2018", + "module": "commonjs", + "allowJs": true, + "strict": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "outDir": "dist" + } +} diff --git a/php-basic-crud/contracts/yarn.lock b/php-basic-crud/contracts/yarn.lock new file mode 100644 index 00000000..264ecf3c --- /dev/null +++ b/php-basic-crud/contracts/yarn.lock @@ -0,0 +1,10371 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" + integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + +"@babel/generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" + integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== + dependencies: + "@babel/types" "^7.16.8" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.13.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + +"@babel/highlight@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" + integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.16.7", "@babel/parser@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" + integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== + +"@babel/plugin-transform-runtime@^7.5.5": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.8.tgz#3339368701103edae708f0fba9e4bfb70a3e5872" + integrity sha512-6Kg2XHPFnIarNweZxmzbgYnnWsXxkx9WQUVk2sksBRL80lBC1RAQV3wQagWxdCHiYHqPN+oenwNIuttlYgIbQQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + semver "^6.3.0" + +"@babel/runtime@^7.5.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.13.0": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.8.tgz#bab2f2b09a5fe8a8d9cad22cbfe3ba1d126fef9c" + integrity sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.8" + "@babel/types" "^7.16.8" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.16.7", "@babel/types@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" + integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@cartesi/logger@^0.7.0": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@cartesi/logger/-/logger-0.7.3.tgz#846acd43ac67ad27874b2c4e7dc236c0efe5d050" + integrity sha512-NtoTB/V8ORlJRczG+dS0JSPS7zNW9iqZp4ihFUdmJeaGd77EpF8eU3NZhh5WR14WhoRgvmqRfsRaH6pLxfp9Rg== + dependencies: + "@cartesi/util" "^2.0.1" + +"@cartesi/rollups@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@cartesi/rollups/-/rollups-0.1.3.tgz#0d8016b6a809b898dc168a3fbaded818ef4ea541" + integrity sha512-kv6y4zcb5JR493AhnrADIGV+Fdcw2414UflscjM6uMLRhnilrW2mYVrlhWvRixs4mUb8o0sdFp5yAgN4r2UFEQ== + dependencies: + "@cartesi/logger" "^0.7.0" + "@cartesi/util" "^3.1.2" + "@openzeppelin/contracts" "^4.1.0" + graphql-tag "^2.12.5" + solidity-bytes-utils "^0.8.0" + +"@cartesi/util@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@cartesi/util/-/util-2.0.1.tgz#fcc7bc3e7e9596c7505aa54a1de0923017692a50" + integrity sha512-gxx9MX8QI6aKr6WrEy9aRcGXIpHAAfG7j/jj6on6D/yrfW4ZLv3uE9HkDd3DBO1qwrWTPEdOg2RAOc9ae0y1Pw== + dependencies: + "@openzeppelin/contracts" "3.2.1-solc-0.7" + +"@cartesi/util@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@cartesi/util/-/util-3.1.2.tgz#332c876017a081ba8aeebf6f1237b5d63ad8f34d" + integrity sha512-7nHX+3tBQaG2RagV1hfxWCfYoL2IW4pz6fOcSg/fi6JTkpsicny8uAkUIW+2Eybf7vPIKjQDBQQ4yThvytSCZA== + +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + +"@ensdomains/ens@^0.4.4": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/resolver@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== + +"@ethereum-waffle/chai@^3.4.0": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.1.tgz#500b59db766a490cb19a7f74ac75a1c3cf86049b" + integrity sha512-8mjgjWCe8XSCWuyJgVtJY8sm00VTczGBTDxBejgEBWN/J9x7QD8jdmWW8bfxdnqZbxiDCTvRFL58Wmd254BEqQ== + dependencies: + "@ethereum-waffle/provider" "^3.4.0" + ethers "^5.4.7" + +"@ethereum-waffle/compiler@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.4.0.tgz#68917321212563544913de33e408327745cb1284" + integrity sha512-a2wxGOoB9F1QFRE+Om7Cz2wn+pxM/o7a0a6cbwhaS2lECJgFzeN9xEkVrKahRkF4gEfXGcuORg4msP0Asxezlw== + dependencies: + "@resolver-engine/imports" "^0.3.3" + "@resolver-engine/imports-fs" "^0.3.3" + "@typechain/ethers-v5" "^2.0.0" + "@types/mkdirp" "^0.5.2" + "@types/node-fetch" "^2.5.5" + ethers "^5.0.1" + mkdirp "^0.5.1" + node-fetch "^2.6.1" + solc "^0.6.3" + ts-generator "^0.1.1" + typechain "^3.0.0" + +"@ethereum-waffle/ens@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.3.1.tgz#0f1b7ac4fc156641c18accd60f8ce256e2c475cf" + integrity sha512-xSjNWnT2Iwii3J3XGqD+F5yLEOzQzLHNLGfI5KIXdtQ4FHgReW/AMGRgPPLi+n+SP08oEQWJ3sEKrvbFlwJuaA== + dependencies: + "@ensdomains/ens" "^0.4.4" + "@ensdomains/resolver" "^0.2.4" + ethers "^5.5.2" + +"@ethereum-waffle/mock-contract@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.3.1.tgz#dfd53a6e184f5e4c5e1119a8aef67f2d88914497" + integrity sha512-h9yChF7IkpJLODg/o9/jlwKwTcXJLSEIq3gewgwUJuBHnhPkJGekcZvsTbximYc+e42QUZrDUATSuTCIryeCEA== + dependencies: + "@ethersproject/abi" "^5.5.0" + ethers "^5.5.2" + +"@ethereum-waffle/provider@^3.4.0": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.4.1.tgz#d59f5741d5ee96a7d5501f455709b38d81c8be2f" + integrity sha512-5iDte7c9g9N1rTRE/P4npwk1Hus/wA2yH850X6sP30mr1IrwSG9NKn6/2SOQkAVJnh9jqyLVg2X9xCODWL8G4A== + dependencies: + "@ethereum-waffle/ens" "^3.3.1" + ethers "^5.5.2" + ganache-core "^2.13.2" + patch-package "^6.2.2" + postinstall-postinstall "^2.1.0" + +"@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.0.tgz#5cf89ea748607597a3f8b038abc986e4ac0b05db" + integrity sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ== + dependencies: + "@ethereumjs/common" "^2.6.0" + "@ethereumjs/tx" "^3.4.0" + ethereumjs-util "^7.1.3" + merkle-patricia-tree "^4.2.2" + +"@ethereumjs/blockchain@^5.5.0": + version "5.5.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz#60f1f50592c06cc47e1704800b88b7d32f609742" + integrity sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA== + dependencies: + "@ethereumjs/block" "^3.6.0" + "@ethereumjs/common" "^2.6.0" + "@ethereumjs/ethash" "^1.1.0" + debug "^2.2.0" + ethereumjs-util "^7.1.3" + level-mem "^5.0.1" + lru-cache "^5.1.1" + semaphore-async-await "^1.5.1" + +"@ethereumjs/common@^2.3.0", "@ethereumjs/common@^2.4.0", "@ethereumjs/common@^2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.0.tgz#feb96fb154da41ee2cc2c5df667621a440f36348" + integrity sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.3" + +"@ethereumjs/ethash@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.1.0.tgz#7c5918ffcaa9cb9c1dc7d12f77ef038c11fb83fb" + integrity sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA== + dependencies: + "@ethereumjs/block" "^3.5.0" + "@types/levelup" "^4.3.0" + buffer-xor "^2.0.1" + ethereumjs-util "^7.1.1" + miller-rabin "^4.0.0" + +"@ethereumjs/tx@^3.2.1", "@ethereumjs/tx@^3.3.0", "@ethereumjs/tx@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" + integrity sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw== + dependencies: + "@ethereumjs/common" "^2.6.0" + ethereumjs-util "^7.1.3" + +"@ethereumjs/vm@^5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.6.0.tgz#e0ca62af07de820143674c30b776b86c1983a464" + integrity sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ== + dependencies: + "@ethereumjs/block" "^3.6.0" + "@ethereumjs/blockchain" "^5.5.0" + "@ethereumjs/common" "^2.6.0" + "@ethereumjs/tx" "^3.4.0" + async-eventemitter "^0.2.4" + core-js-pure "^3.0.1" + debug "^2.2.0" + ethereumjs-util "^7.1.3" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + merkle-patricia-tree "^4.2.2" + rustbn.js "~0.2.0" + +"@ethersproject/abi@5.0.0-beta.153": + version "5.0.0-beta.153" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" + integrity sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg== + dependencies: + "@ethersproject/address" ">=5.0.0-beta.128" + "@ethersproject/bignumber" ">=5.0.0-beta.130" + "@ethersproject/bytes" ">=5.0.0-beta.129" + "@ethersproject/constants" ">=5.0.0-beta.128" + "@ethersproject/hash" ">=5.0.0-beta.128" + "@ethersproject/keccak256" ">=5.0.0-beta.127" + "@ethersproject/logger" ">=5.0.0-beta.129" + "@ethersproject/properties" ">=5.0.0-beta.131" + "@ethersproject/strings" ">=5.0.0-beta.130" + +"@ethersproject/abi@5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.7.tgz#79e52452bd3ca2956d0e1c964207a58ad1a0ee7b" + integrity sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw== + dependencies: + "@ethersproject/address" "^5.0.4" + "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/constants" "^5.0.4" + "@ethersproject/hash" "^5.0.4" + "@ethersproject/keccak256" "^5.0.3" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties" "^5.0.3" + "@ethersproject/strings" "^5.0.4" + +"@ethersproject/abi@5.5.0", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.4.0", "@ethersproject/abi@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.5.0.tgz#fb52820e22e50b854ff15ce1647cc508d6660613" + integrity sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w== + dependencies: + "@ethersproject/address" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/constants" "^5.5.0" + "@ethersproject/hash" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + +"@ethersproject/abstract-provider@5.5.1", "@ethersproject/abstract-provider@^5.5.0": + version "5.5.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5" + integrity sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg== + dependencies: + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/networks" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/transactions" "^5.5.0" + "@ethersproject/web" "^5.5.0" + +"@ethersproject/abstract-signer@5.5.0", "@ethersproject/abstract-signer@^5.4.1", "@ethersproject/abstract-signer@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz#590ff6693370c60ae376bf1c7ada59eb2a8dd08d" + integrity sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA== + dependencies: + "@ethersproject/abstract-provider" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + +"@ethersproject/address@5.5.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.4.0", "@ethersproject/address@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.5.0.tgz#bcc6f576a553f21f3dd7ba17248f81b473c9c78f" + integrity sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw== + dependencies: + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/rlp" "^5.5.0" + +"@ethersproject/base64@5.5.0", "@ethersproject/base64@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090" + integrity sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA== + dependencies: + "@ethersproject/bytes" "^5.5.0" + +"@ethersproject/basex@5.5.0", "@ethersproject/basex@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.5.0.tgz#e40a53ae6d6b09ab4d977bd037010d4bed21b4d3" + integrity sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + +"@ethersproject/bignumber@5.5.0", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.4.1", "@ethersproject/bignumber@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527" + integrity sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + bn.js "^4.11.9" + +"@ethersproject/bytes@5.5.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.4.0", "@ethersproject/bytes@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" + integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog== + dependencies: + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/constants@5.5.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4", "@ethersproject/constants@^5.4.0", "@ethersproject/constants@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.5.0.tgz#d2a2cd7d94bd1d58377d1d66c4f53c9be4d0a45e" + integrity sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ== + dependencies: + "@ethersproject/bignumber" "^5.5.0" + +"@ethersproject/contracts@5.5.0", "@ethersproject/contracts@^5.4.1": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.5.0.tgz#b735260d4bd61283a670a82d5275e2a38892c197" + integrity sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg== + dependencies: + "@ethersproject/abi" "^5.5.0" + "@ethersproject/abstract-provider" "^5.5.0" + "@ethersproject/abstract-signer" "^5.5.0" + "@ethersproject/address" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/constants" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/transactions" "^5.5.0" + +"@ethersproject/hash@5.5.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.4", "@ethersproject/hash@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9" + integrity sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg== + dependencies: + "@ethersproject/abstract-signer" "^5.5.0" + "@ethersproject/address" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + +"@ethersproject/hdnode@5.5.0", "@ethersproject/hdnode@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.5.0.tgz#4a04e28f41c546f7c978528ea1575206a200ddf6" + integrity sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q== + dependencies: + "@ethersproject/abstract-signer" "^5.5.0" + "@ethersproject/basex" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/pbkdf2" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/sha2" "^5.5.0" + "@ethersproject/signing-key" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + "@ethersproject/transactions" "^5.5.0" + "@ethersproject/wordlists" "^5.5.0" + +"@ethersproject/json-wallets@5.5.0", "@ethersproject/json-wallets@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz#dd522d4297e15bccc8e1427d247ec8376b60e325" + integrity sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ== + dependencies: + "@ethersproject/abstract-signer" "^5.5.0" + "@ethersproject/address" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/hdnode" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/pbkdf2" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/random" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + "@ethersproject/transactions" "^5.5.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.5.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3", "@ethersproject/keccak256@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.5.0.tgz#e4b1f9d7701da87c564ffe336f86dcee82983492" + integrity sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg== + dependencies: + "@ethersproject/bytes" "^5.5.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@5.5.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5", "@ethersproject/logger@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" + integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg== + +"@ethersproject/networks@5.5.2", "@ethersproject/networks@^5.5.0": + version "5.5.2" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.5.2.tgz#784c8b1283cd2a931114ab428dae1bd00c07630b" + integrity sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ== + dependencies: + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/pbkdf2@5.5.0", "@ethersproject/pbkdf2@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz#e25032cdf02f31505d47afbf9c3e000d95c4a050" + integrity sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/sha2" "^5.5.0" + +"@ethersproject/properties@5.5.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.5.0.tgz#61f00f2bb83376d2071baab02245f92070c59995" + integrity sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA== + dependencies: + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/providers@5.5.2", "@ethersproject/providers@^5.4.4": + version "5.5.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.5.2.tgz#131ccf52dc17afd0ab69ed444b8c0e3a27297d99" + integrity sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ== + dependencies: + "@ethersproject/abstract-provider" "^5.5.0" + "@ethersproject/abstract-signer" "^5.5.0" + "@ethersproject/address" "^5.5.0" + "@ethersproject/basex" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/constants" "^5.5.0" + "@ethersproject/hash" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/networks" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/random" "^5.5.0" + "@ethersproject/rlp" "^5.5.0" + "@ethersproject/sha2" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + "@ethersproject/transactions" "^5.5.0" + "@ethersproject/web" "^5.5.0" + bech32 "1.1.4" + ws "7.4.6" + +"@ethersproject/random@5.5.1", "@ethersproject/random@^5.5.0": + version "5.5.1" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.5.1.tgz#7cdf38ea93dc0b1ed1d8e480ccdaf3535c555415" + integrity sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/rlp@5.5.0", "@ethersproject/rlp@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.5.0.tgz#530f4f608f9ca9d4f89c24ab95db58ab56ab99a0" + integrity sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/sha2@5.5.0", "@ethersproject/sha2@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.5.0.tgz#a40a054c61f98fd9eee99af2c3cc6ff57ec24db7" + integrity sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.5.0", "@ethersproject/signing-key@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.5.0.tgz#2aa37169ce7e01e3e80f2c14325f624c29cedbe0" + integrity sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + bn.js "^4.11.9" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.5.0", "@ethersproject/solidity@^5.4.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.5.0.tgz#2662eb3e5da471b85a20531e420054278362f93f" + integrity sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw== + dependencies: + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/sha2" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + +"@ethersproject/strings@5.5.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4", "@ethersproject/strings@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.5.0.tgz#e6784d00ec6c57710755699003bc747e98c5d549" + integrity sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/constants" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/transactions@5.5.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.4.0", "@ethersproject/transactions@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.5.0.tgz#7e9bf72e97bcdf69db34fe0d59e2f4203c7a2908" + integrity sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA== + dependencies: + "@ethersproject/address" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/constants" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/rlp" "^5.5.0" + "@ethersproject/signing-key" "^5.5.0" + +"@ethersproject/units@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.5.0.tgz#104d02db5b5dc42cc672cc4587bafb87a95ee45e" + integrity sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag== + dependencies: + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/constants" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + +"@ethersproject/wallet@5.5.0", "@ethersproject/wallet@^5.4.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.5.0.tgz#322a10527a440ece593980dca6182f17d54eae75" + integrity sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q== + dependencies: + "@ethersproject/abstract-provider" "^5.5.0" + "@ethersproject/abstract-signer" "^5.5.0" + "@ethersproject/address" "^5.5.0" + "@ethersproject/bignumber" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/hash" "^5.5.0" + "@ethersproject/hdnode" "^5.5.0" + "@ethersproject/json-wallets" "^5.5.0" + "@ethersproject/keccak256" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/random" "^5.5.0" + "@ethersproject/signing-key" "^5.5.0" + "@ethersproject/transactions" "^5.5.0" + "@ethersproject/wordlists" "^5.5.0" + +"@ethersproject/web@5.5.1", "@ethersproject/web@^5.5.0": + version "5.5.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.5.1.tgz#cfcc4a074a6936c657878ac58917a61341681316" + integrity sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg== + dependencies: + "@ethersproject/base64" "^5.5.0" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + +"@ethersproject/wordlists@5.5.0", "@ethersproject/wordlists@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.5.0.tgz#aac74963aa43e643638e5172353d931b347d584f" + integrity sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q== + dependencies: + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/hash" "^5.5.0" + "@ethersproject/logger" "^5.5.0" + "@ethersproject/properties" "^5.5.0" + "@ethersproject/strings" "^5.5.0" + +"@graphql-typed-document-node/core@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.1.tgz#076d78ce99822258cf813ecc1e7fa460fa74d052" + integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg== + +"@metamask/safe-event-emitter@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" + integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@nomiclabs/hardhat-ethers@^2.0.3": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.4.tgz#288889c338acaf47cabd29020e561d0077b7efcf" + integrity sha512-7LMR344TkdCYkMVF9LuC9VU2NBIi84akQiwqm7OufpWaDgHbWhuanY53rk3SVAW0E4HBk5xn5wl5+bN5f+Mq5w== + +"@nomiclabs/hardhat-etherscan@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.0.tgz#06e0d59787f01f1296d829e8d43fece50e7ffff1" + integrity sha512-E5s35dCHmzuY6pFqlgTdDGQr2xIyUJ3f91m6e7HYlPGz0FGzad9Nem/y0L7L3FHG4LPYg1UObkQVUzqBjtyAOA== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^5.0.2" + debug "^4.1.1" + fs-extra "^7.0.1" + node-fetch "^2.6.0" + semver "^6.3.0" + +"@nomiclabs/hardhat-waffle@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.1.tgz#5d43654fba780720c5033dea240fe14f70ef4bd2" + integrity sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ== + dependencies: + "@types/sinon-chai" "^3.2.3" + "@types/web3" "1.0.19" + +"@openzeppelin/contracts@3.2.1-solc-0.7": + version "3.2.1-solc-0.7" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.2.1-solc-0.7.tgz#067a60918b935d4733208edb3d7e35cd1d51026b" + integrity sha512-VfKZE9L2HNaZVBR7l5yHbRmap3EiVw9F5iVXRRDdgfnA9vQ1yFanrs0VYmdo2VIXC+EsI9wPPYZY9Ic7/qDBdw== + +"@openzeppelin/contracts@^4.1.0": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.2.tgz#4e889c9c66e736f7de189a53f8ba5b8d789425c2" + integrity sha512-NyJV7sJgoGYqbtNUWgzzOGW4T6rR19FmX1IJgXGdapGPWsuMelGJn9h03nos0iqfforCbCB0iYIR0MtIuIFLLw== + +"@resolver-engine/core@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" + integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== + dependencies: + debug "^3.1.0" + is-url "^1.2.4" + request "^2.85.0" + +"@resolver-engine/fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" + integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports-fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" + integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== + dependencies: + "@resolver-engine/fs" "^0.3.3" + "@resolver-engine/imports" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" + integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + hosted-git-info "^2.6.0" + path-browserify "^1.0.0" + url "^0.11.0" + +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sentry/node@^5.18.1": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== + dependencies: + "@sentry/core" "5.30.0" + "@sentry/hub" "5.30.0" + "@sentry/tracing" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/tracing@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== + +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== + dependencies: + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^7.1.0": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@solidity-parser/parser@^0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.13.2.tgz#b6c71d8ca0b382d90a7bbed241f9bc110af65cbe" + integrity sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@solidity-parser/parser@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.0.tgz#d51f074efb0acce0e953ec48133561ed710cebc0" + integrity sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@truffle/error@^0.0.14": + version "0.0.14" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.0.14.tgz#59683b5407bede7bddf16d80dc5592f9c5e5fa05" + integrity sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA== + +"@truffle/hdwallet-provider@latest": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-2.0.0.tgz#4301afbff082b2ddcccfe9c455821dd87e74dbdd" + integrity sha512-jquMJCMeHYhvPyZiIhLSWGzGkGK7Xswbw9kcti3USPIMP/AhVNVPe8E0fPurBLUb/Wvl6VW/6Z514JsmzC/IQA== + dependencies: + "@ethereumjs/common" "^2.4.0" + "@ethereumjs/tx" "^3.3.0" + eth-sig-util "^3.0.1" + ethereum-cryptography "^0.1.3" + ethereum-protocol "^1.0.1" + ethereumjs-util "^6.1.0" + ethereumjs-wallet "^1.0.1" + web3-provider-engine "16.0.3" + +"@truffle/interface-adapter@^0.5.8": + version "0.5.8" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.8.tgz#76cfd34374d85849e1164de1a3d5a3dce0dc5d01" + integrity sha512-vvy3xpq36oLgjjy8KE9l2Jabg3WcGPOt18tIyMfTQX9MFnbHoQA2Ne2i8xsd4p6KfxIqSjAB53Q9/nScAqY0UQ== + dependencies: + bn.js "^5.1.3" + ethers "^4.0.32" + web3 "1.5.3" + +"@truffle/provider@^0.2.24": + version "0.2.42" + resolved "https://registry.yarnpkg.com/@truffle/provider/-/provider-0.2.42.tgz#9da6a144b3c9188cdb587451dd7bd907b4c7164b" + integrity sha512-ZNoglPho4alYIjJR+sLTgX0x6ho7m4OAUWuJ50RAWmoEqYc4AM6htdrI+lTSoRrOHHbmgasv22a7rFPMnmDrTg== + dependencies: + "@truffle/error" "^0.0.14" + "@truffle/interface-adapter" "^0.5.8" + web3 "1.5.3" + +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@typechain/ethers-v5@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz#cd3ca1590240d587ca301f4c029b67bfccd08810" + integrity sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw== + dependencies: + ethers "^5.0.2" + +"@typechain/ethers-v5@^8.0.5": + version "8.0.5" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-8.0.5.tgz#d469420e9a73deb7fa076cde9edb45d713dd1b8c" + integrity sha512-ntpj4cS3v4WlDu+hSKSyj9A3o1tKtWC30RX1gobeYymZColeJiUemC1Kgfa0MWGmInm5CKxoHVhEvYVgPOZn1A== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/hardhat@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-3.1.0.tgz#88bd9e9d55e30fbece6fbb34c03ecd40a8b2013a" + integrity sha512-C6Be6l+vTpao19PvMH2CB/lhL1TRLkhdPkvQCF/zqkY1e+0iqY2Bb9Jd3PTt6I8QvMm89ZDerrCJC9927ZHmlg== + dependencies: + fs-extra "^9.1.0" + +"@types/abstract-leveldown@*": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#f055979a99f7654e84d6b8e6267419e9c4cfff87" + integrity sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ== + +"@types/bn.js@*", "@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + +"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/chai@*": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.0.tgz#23509ebc1fa32f1b4d50d6a66c4032d5b8eaabdc" + integrity sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw== + +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/level-errors@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/level-errors/-/level-errors-3.0.0.tgz#15c1f4915a5ef763b51651b15e90f6dc081b96a8" + integrity sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ== + +"@types/levelup@^4.3.0": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-4.3.3.tgz#4dc2b77db079b1cf855562ad52321aa4241b8ef4" + integrity sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA== + dependencies: + "@types/abstract-leveldown" "*" + "@types/level-errors" "*" + "@types/node" "*" + +"@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/mocha@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.0.0.tgz#3205bcd15ada9bc681ac20bef64e9e6df88fd297" + integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA== + +"@types/node-fetch@^2.5.5": + version "2.5.12" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" + integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*", "@types/node@^17.0.8": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" + integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== + +"@types/node@^12.12.6": + version "12.20.41" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.41.tgz#81d7734c5257da9f04354bd9084a6ebbdd5198a5" + integrity sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/pbkdf2@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" + integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== + dependencies: + "@types/node" "*" + +"@types/prettier@^2.1.1": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.3.tgz#a3c65525b91fca7da00ab1a3ac2b5a2a4afbffbf" + integrity sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w== + +"@types/qs@^6.9.7": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/resolve@^0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" + integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== + dependencies: + "@types/node" "*" + +"@types/sinon-chai@^3.2.3": + version "3.2.8" + resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.8.tgz#5871d09ab50d671d8e6dd72e9073f8e738ac61dc" + integrity sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g== + dependencies: + "@types/chai" "*" + "@types/sinon" "*" + +"@types/sinon@*": + version "10.0.6" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.6.tgz#bc3faff5154e6ecb69b797d311b7cf0c1b523a1d" + integrity sha512-6EF+wzMWvBNeGrfP3Nx60hhx+FfwSg1JJBLAAP/IdIUq0EYkqCYf70VT3PhuhPX9eLD+Dp+lNdpb/ZeHG8Yezg== + dependencies: + "@sinonjs/fake-timers" "^7.1.0" + +"@types/underscore@*": + version "1.11.4" + resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.4.tgz#62e393f8bc4bd8a06154d110c7d042a93751def3" + integrity sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg== + +"@types/web3@1.0.19": + version "1.0.19" + resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.19.tgz#46b85d91d398ded9ab7c85a5dd57cb33ac558924" + integrity sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A== + dependencies: + "@types/bn.js" "*" + "@types/underscore" "*" + +"@urql/core@^2.4.3": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@urql/core/-/core-2.4.3.tgz#af35355cd2e3eeef4657f91616098e7cba8154dc" + integrity sha512-FpapxUKF0nLdzRLoB1QsudDjeLXJhBwzkzl8bSOJ6Cnj7LRRKJ+dYdqHfqGykswB/ILrkZks2Isp4a4BhqyUow== + dependencies: + "@graphql-typed-document-node/core" "^3.1.1" + wonka "^4.0.14" + +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abstract-leveldown@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" + integrity sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: + version "2.7.2" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" + integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" + integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" + integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ== + dependencies: + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +abstract-leveldown@~2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" + integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@~6.2.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" + integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ== + dependencies: + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^5.0.0: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^6.0.7: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +acorn@^8.4.1: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +adm-zip@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= + +aes-js@^3.1.1, aes-js@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ajv@^6.10.2, ajv@^6.12.3, ajv@^6.6.1, ajv@^6.9.1: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +antlr4@4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" + integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +anymatch@~3.1.1, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-back@^1.0.3, array-back@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" + integrity sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs= + dependencies: + typical "^2.6.0" + +array-back@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" + integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== + dependencies: + typical "^2.6.1" + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-parents@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" + integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== + dependencies: + async "^2.4.0" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async-mutex@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.6.tgz#0d7a3deb978bc2b984d5908a2038e1ae2e54ff40" + integrity sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw== + dependencies: + tslib "^2.0.0" + +async@1.x, async@^1.4.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + dependencies: + lodash "^4.17.11" + +async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +axios@^0.21.1: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.14, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.3.1" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz#d66183bf10976ea677f4149a7fcc4d8df43d4060" + integrity sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + core-js-compat "^3.20.0" + +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babelify@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" + integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU= + dependencies: + babel-core "^6.0.14" + object-assign "^4.0.0" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backoff@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" + integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8= + dependencies: + precond "0.2" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2, base-x@^3.0.8: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bignumber.js@^9.0.0, bignumber.js@^9.0.1: + version "9.0.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" + integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bip39@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" + integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== + dependencies: + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + unorm "^1.3.3" + +blakejs@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702" + integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg== + +bluebird@^3.5.0, bluebird@^3.5.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +body-parser@1.19.1, body-parser@^1.16.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +browserslist@^4.17.5, browserslist@^4.19.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +btoa@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" + integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer-xor@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" + integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== + dependencies: + safe-buffer "^5.1.1" + +buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bufferutil@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" + integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== + dependencies: + node-gyp-build "^4.3.0" + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +bytewise-core@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" + integrity sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI= + dependencies: + typewise-core "^1.2" + +bytewise@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" + integrity sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4= + dependencies: + bytewise-core "^1.2.2" + typewise "^1.0.3" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +cachedown@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" + integrity sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU= + dependencies: + abstract-leveldown "^2.4.1" + lru-cache "^3.2.0" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30000844: + version "1.0.30001298" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz#0e690039f62e91c3ea581673d716890512e7ec52" + integrity sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ== + +caniuse-lite@^1.0.30001286: + version "1.0.30001300" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz#11ab6c57d3eb6f964cba950401fd00a146786468" + integrity sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +cbor@^5.0.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" + integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== + dependencies: + bignumber.js "^9.0.1" + nofilter "^1.0.4" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +checkpoint-store@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" + integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY= + dependencies: + functional-red-black-tree "^1.0.1" + +chokidar@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" + integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.2.0" + optionalDependencies: + fsevents "~2.1.1" + +chokidar@^3.4.0, chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@2.1.2, clone@^2.0.0, clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + +command-line-args@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" + integrity sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA== + dependencies: + array-back "^2.0.0" + find-replace "^1.0.3" + typical "^2.6.1" + +command-line-args@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.0.tgz#087b02748272169741f1fd7c785b295df079b9be" + integrity sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.1.tgz#c908e28686108917758a49f45efb4f02f76bc03f" + integrity sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA== + dependencies: + array-back "^4.0.1" + chalk "^2.4.2" + table-layout "^1.0.1" + typical "^5.2.0" + +commander@2.18.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" + integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== + +commander@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-hash@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== + dependencies: + cids "^0.7.1" + multicodec "^0.5.5" + multihashes "^0.4.15" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1, cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +cookiejar@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" + integrity sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copyfiles@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5" + integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg== + dependencies: + glob "^7.0.5" + minimatch "^3.0.3" + mkdirp "^1.0.4" + noms "0.0.0" + through2 "^2.0.1" + untildify "^4.0.0" + yargs "^16.1.0" + +core-js-compat@^3.20.0: + version "3.20.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" + integrity sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw== + dependencies: + browserslist "^4.19.1" + semver "7.0.0" + +core-js-pure@^3.0.1: + version "3.20.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.20.2.tgz#5d263565f0e34ceeeccdc4422fae3e84ca6b8c0f" + integrity sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg== + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^5.0.7: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +cosmiconfig@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +crc-32@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" + integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-fetch@^2.1.0, cross-fetch@^2.1.1: + version "2.2.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.5.tgz#afaf5729f3b6c78d89c9296115c9f142541a5705" + integrity sha512-xqYAhQb4NhCJSRym03dwxpP1bYXpK3y7UN83Bo2WFi3x1Zmzn0SL/6xGoPr+gpt4WmNrgCCX3HPysvOwFOW36w== + dependencies: + node-fetch "2.6.1" + whatwg-fetch "2.0.4" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +death@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" + integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-equal@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +deferred-leveldown@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" + integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== + dependencies: + abstract-leveldown "~2.6.0" + +deferred-leveldown@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" + integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== + dependencies: + abstract-leveldown "~5.0.0" + inherits "^2.0.3" + +deferred-leveldown@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" + integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== + dependencies: + abstract-leveldown "~6.2.1" + inherits "^2.0.3" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-port@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +dotignore@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" + integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== + dependencies: + minimatch "^3.0.4" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.47: + version "1.4.41" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.41.tgz#0b2e126796e7fafb9fd71e29304468b9d0af5d65" + integrity sha512-VQEXEJc+8rJIva85H8EPtB5Ux9g8TzkNGBanqphM9ZWMZ34elueKJ+5g+BPhz3Lk8gkujfQRcIZ+fpA0btUIuw== + +electron-to-chromium@^1.4.17: + version "1.4.47" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.47.tgz#5d5535cdbca2b9264abee4d6ea121995e9554bbe" + integrity sha512-ZHc8i3/cgeCRK/vC7W2htAG6JqUmOUgDNn/f9yY9J8UjfLjwzwOVEt4MWmgJAdvmxyrsR5KIFA/6+kUHGY0eUA== + +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.0.0.tgz#96559e19f82231b436403e059571241d627c42b8" + integrity sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encode-utf8@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding-down@5.0.4, encoding-down@~5.0.0: + version "5.0.4" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" + integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== + dependencies: + abstract-leveldown "^5.0.0" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + xtend "^4.0.1" + +encoding-down@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" + integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== + dependencies: + abstract-leveldown "^6.2.1" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enquirer@^2.3.0, enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.5, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint@^5.6.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eth-block-tracker@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" + integrity sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug== + dependencies: + eth-query "^2.1.0" + ethereumjs-tx "^1.3.3" + ethereumjs-util "^5.1.3" + ethjs-util "^0.1.3" + json-rpc-engine "^3.6.0" + pify "^2.3.0" + tape "^4.6.3" + +eth-block-tracker@^4.4.2: + version "4.4.3" + resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-4.4.3.tgz#766a0a0eb4a52c867a28328e9ae21353812cf626" + integrity sha512-A8tG4Z4iNg4mw5tP1Vung9N9IjgMNqpiMoJ/FouSFwNCGHv2X0mmOYwtQOJzki6XN7r7Tyo01S29p7b224I4jw== + dependencies: + "@babel/plugin-transform-runtime" "^7.5.5" + "@babel/runtime" "^7.5.5" + eth-query "^2.1.0" + json-rpc-random-id "^1.0.1" + pify "^3.0.0" + safe-event-emitter "^1.0.1" + +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + +eth-json-rpc-filters@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-4.2.2.tgz#eb35e1dfe9357ace8a8908e7daee80b2cd60a10d" + integrity sha512-DGtqpLU7bBg63wPMWg1sCpkKCf57dJ+hj/k3zF26anXMzkmtSBDExL8IhUu7LUd34f0Zsce3PYNO2vV2GaTzaw== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + async-mutex "^0.2.6" + eth-json-rpc-middleware "^6.0.0" + eth-query "^2.1.2" + json-rpc-engine "^6.1.0" + pify "^5.0.0" + +eth-json-rpc-infura@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" + integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== + dependencies: + cross-fetch "^2.1.1" + eth-json-rpc-middleware "^1.5.0" + json-rpc-engine "^3.4.0" + json-rpc-error "^2.0.0" + +eth-json-rpc-infura@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-5.1.0.tgz#e6da7dc47402ce64c54e7018170d89433c4e8fb6" + integrity sha512-THzLye3PHUSGn1EXMhg6WTLW9uim7LQZKeKaeYsS9+wOBcamRiCQVGHa6D2/4P0oS0vSaxsBnU/J6qvn0MPdow== + dependencies: + eth-json-rpc-middleware "^6.0.0" + eth-rpc-errors "^3.0.0" + json-rpc-engine "^5.3.0" + node-fetch "^2.6.0" + +eth-json-rpc-middleware@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" + integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q== + dependencies: + async "^2.5.0" + eth-query "^2.1.2" + eth-tx-summary "^3.1.2" + ethereumjs-block "^1.6.0" + ethereumjs-tx "^1.3.3" + ethereumjs-util "^5.1.2" + ethereumjs-vm "^2.1.0" + fetch-ponyfill "^4.0.0" + json-rpc-engine "^3.6.0" + json-rpc-error "^2.0.0" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + tape "^4.6.3" + +eth-json-rpc-middleware@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-6.0.0.tgz#4fe16928b34231a2537856f08a5ebbc3d0c31175" + integrity sha512-qqBfLU2Uq1Ou15Wox1s+NX05S9OcAEL4JZ04VZox2NS0U+RtCMjSxzXhLFWekdShUPZ+P8ax3zCO2xcPrp6XJQ== + dependencies: + btoa "^1.2.1" + clone "^2.1.1" + eth-query "^2.1.2" + eth-rpc-errors "^3.0.0" + eth-sig-util "^1.4.2" + ethereumjs-util "^5.1.2" + json-rpc-engine "^5.3.0" + json-stable-stringify "^1.0.1" + node-fetch "^2.6.1" + pify "^3.0.0" + safe-event-emitter "^1.0.1" + +eth-lib@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" + integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4= + dependencies: + json-rpc-random-id "^1.0.0" + xtend "^4.0.1" + +eth-rpc-errors@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz#d7b22653c70dbf9defd4ef490fd08fe70608ca10" + integrity sha512-iPPNHPrLwUlR9xCSYm7HHQjWBasor3+KZfRvwEWxMz3ca0yqnlBeJrnyphkGIXZ4J7AMAaOLmwy4AWhnxOiLxg== + dependencies: + fast-safe-stringify "^2.0.6" + +eth-rpc-errors@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.3.tgz#6ddb6190a4bf360afda82790bb7d9d5e724f423a" + integrity sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg== + dependencies: + fast-safe-stringify "^2.0.6" + +eth-sig-util@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-3.0.0.tgz#75133b3d7c20a5731af0690c385e184ab942b97e" + integrity sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ== + dependencies: + buffer "^5.2.1" + elliptic "^6.4.0" + ethereumjs-abi "0.6.5" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.0" + tweetnacl-util "^0.15.0" + +eth-sig-util@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" + integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= + dependencies: + ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" + ethereumjs-util "^5.1.1" + +eth-sig-util@^2.5.2: + version "2.5.4" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.4.tgz#577b01fe491b6bf59b0464be09633e20c1677bc5" + integrity sha512-aCMBwp8q/4wrW4QLsF/HYBOSA7TpLKmkVwP3pYQNkEEseW2Rr8Z5Uxc9/h6HX+OG3tuHo+2bINVSihIeBfym6A== + dependencies: + ethereumjs-abi "0.6.8" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.0" + +eth-sig-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-3.0.1.tgz#8753297c83a3f58346bd13547b59c4b2cd110c96" + integrity sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ== + dependencies: + ethereumjs-abi "^0.6.8" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.0" + +eth-tx-summary@^3.1.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" + integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg== + dependencies: + async "^2.1.2" + clone "^2.0.0" + concat-stream "^1.5.1" + end-of-stream "^1.1.0" + eth-query "^2.0.2" + ethereumjs-block "^1.4.1" + ethereumjs-tx "^1.1.1" + ethereumjs-util "^5.0.1" + ethereumjs-vm "^2.6.0" + through2 "^2.0.3" + +ethashjs@~0.0.7: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.8.tgz#227442f1bdee409a548fb04136e24c874f3aa6f9" + integrity sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw== + dependencies: + async "^2.1.2" + buffer-xor "^2.0.1" + ethereumjs-util "^7.0.2" + miller-rabin "^4.0.0" + +ethereum-bloom-filters@^1.0.6: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" + integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + dependencies: + js-sha3 "^0.8.0" + +ethereum-common@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" + integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== + +ethereum-common@^0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" + integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= + +ethereum-cryptography@^0.1.2, ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + blakejs "^1.1.0" + browserify-aes "^1.2.0" + bs58check "^2.1.2" + create-hash "^1.2.0" + create-hmac "^1.1.7" + hash.js "^1.1.7" + keccak "^3.0.0" + pbkdf2 "^3.0.17" + randombytes "^2.1.0" + safe-buffer "^5.1.2" + scrypt-js "^3.0.0" + secp256k1 "^4.0.1" + setimmediate "^1.0.5" + +ethereum-protocol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz#b7d68142f4105e0ae7b5e178cf42f8d4dc4b93cf" + integrity sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg== + +ethereum-waffle@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.4.0.tgz#990b3c6c26db9c2dd943bf26750a496f60c04720" + integrity sha512-ADBqZCkoSA5Isk486ntKJVjFEawIiC+3HxNqpJqONvh3YXBTNiRfXvJtGuAFLXPG91QaqkGqILEHANAo7j/olQ== + dependencies: + "@ethereum-waffle/chai" "^3.4.0" + "@ethereum-waffle/compiler" "^3.4.0" + "@ethereum-waffle/mock-contract" "^3.3.0" + "@ethereum-waffle/provider" "^3.4.0" + ethers "^5.0.1" + +ethereumjs-abi@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" + integrity sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE= + dependencies: + bn.js "^4.10.0" + ethereumjs-util "^4.3.0" + +ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": + version "0.6.8" + resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0" + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" + integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== + dependencies: + ethereumjs-util "^6.0.0" + rlp "^2.2.1" + safe-buffer "^5.1.1" + +ethereumjs-account@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" + integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== + dependencies: + ethereumjs-util "^5.0.0" + rlp "^2.0.0" + safe-buffer "^5.1.1" + +ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" + integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== + dependencies: + async "^2.0.1" + ethereumjs-common "^1.5.0" + ethereumjs-tx "^2.1.1" + ethereumjs-util "^5.0.0" + merkle-patricia-tree "^2.1.2" + +ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" + integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== + dependencies: + async "^2.0.1" + ethereum-common "0.2.0" + ethereumjs-tx "^1.2.2" + ethereumjs-util "^5.0.0" + merkle-patricia-tree "^2.1.2" + +ethereumjs-blockchain@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz#30f2228dc35f6dcf94423692a6902604ae34960f" + integrity sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ== + dependencies: + async "^2.6.1" + ethashjs "~0.0.7" + ethereumjs-block "~2.2.2" + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.1.0" + flow-stoplight "^1.0.0" + level-mem "^3.0.1" + lru-cache "^5.1.1" + rlp "^2.2.2" + semaphore "^1.1.0" + +ethereumjs-common@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" + integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== + +ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" + integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== + +ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" + integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== + dependencies: + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.0.0" + +ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" + integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== + dependencies: + ethereum-common "^0.0.18" + ethereumjs-util "^5.0.0" + +ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.3" + +ethereumjs-util@^4.3.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" + integrity sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w== + dependencies: + bn.js "^4.8.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + rlp "^2.0.0" + +ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" + integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== + dependencies: + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "^0.1.3" + rlp "^2.0.0" + safe-buffer "^5.1.1" + +ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" + integrity sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + +ethereumjs-vm@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" + integrity sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA== + dependencies: + async "^2.1.2" + async-eventemitter "^0.2.2" + core-js-pure "^3.0.1" + ethereumjs-account "^3.0.0" + ethereumjs-block "^2.2.2" + ethereumjs-blockchain "^4.0.3" + ethereumjs-common "^1.5.0" + ethereumjs-tx "^2.1.2" + ethereumjs-util "^6.2.0" + fake-merkle-patricia-tree "^1.0.1" + functional-red-black-tree "^1.0.1" + merkle-patricia-tree "^2.3.2" + rustbn.js "~0.2.0" + safe-buffer "^5.1.1" + util.promisify "^1.0.0" + +ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" + integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== + dependencies: + async "^2.1.2" + async-eventemitter "^0.2.2" + ethereumjs-account "^2.0.3" + ethereumjs-block "~2.2.0" + ethereumjs-common "^1.1.0" + ethereumjs-util "^6.0.0" + fake-merkle-patricia-tree "^1.0.1" + functional-red-black-tree "^1.0.1" + merkle-patricia-tree "^2.3.2" + rustbn.js "~0.2.0" + safe-buffer "^5.1.1" + +ethereumjs-wallet@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" + integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA== + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereum-cryptography "^0.1.3" + ethereumjs-util "^6.0.0" + randombytes "^2.0.6" + safe-buffer "^5.1.2" + scryptsy "^1.2.1" + utf8 "^3.0.0" + uuid "^3.3.2" + +ethereumjs-wallet@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz#2c000504b4c71e8f3782dabe1113d192522e99b6" + integrity sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA== + dependencies: + aes-js "^3.1.2" + bs58check "^2.1.2" + ethereum-cryptography "^0.1.3" + ethereumjs-util "^7.1.2" + randombytes "^2.1.0" + scrypt-js "^3.0.1" + utf8 "^3.0.0" + uuid "^8.3.2" + +ethers@^4.0.32: + version "4.0.49" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" + integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== + dependencies: + aes-js "3.0.0" + bn.js "^4.11.9" + elliptic "6.5.4" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.4" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" + +ethers@^5.0.1, ethers@^5.0.2, ethers@^5.4.7, ethers@^5.5.2: + version "5.5.3" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.5.3.tgz#1e361516711c0c3244b6210e7e3ecabf0c75fca0" + integrity sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g== + dependencies: + "@ethersproject/abi" "5.5.0" + "@ethersproject/abstract-provider" "5.5.1" + "@ethersproject/abstract-signer" "5.5.0" + "@ethersproject/address" "5.5.0" + "@ethersproject/base64" "5.5.0" + "@ethersproject/basex" "5.5.0" + "@ethersproject/bignumber" "5.5.0" + "@ethersproject/bytes" "5.5.0" + "@ethersproject/constants" "5.5.0" + "@ethersproject/contracts" "5.5.0" + "@ethersproject/hash" "5.5.0" + "@ethersproject/hdnode" "5.5.0" + "@ethersproject/json-wallets" "5.5.0" + "@ethersproject/keccak256" "5.5.0" + "@ethersproject/logger" "5.5.0" + "@ethersproject/networks" "5.5.2" + "@ethersproject/pbkdf2" "5.5.0" + "@ethersproject/properties" "5.5.0" + "@ethersproject/providers" "5.5.2" + "@ethersproject/random" "5.5.1" + "@ethersproject/rlp" "5.5.0" + "@ethersproject/sha2" "5.5.0" + "@ethersproject/signing-key" "5.5.0" + "@ethersproject/solidity" "5.5.0" + "@ethersproject/strings" "5.5.0" + "@ethersproject/transactions" "5.5.0" + "@ethersproject/units" "5.5.0" + "@ethersproject/wallet" "5.5.0" + "@ethersproject/web" "5.5.1" + "@ethersproject/wordlists" "5.5.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@0.1.6, ethjs-util@^0.1.3: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express@^4.14.0: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fake-merkle-patricia-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" + integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM= + dependencies: + checkpoint-store "^1.1.0" + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.0.3: + version "3.2.10" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.10.tgz#2734f83baa7f43b7fd41e13bc34438f4ffe284ee" + integrity sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-safe-stringify@^2.0.6: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +fetch-ponyfill@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" + integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM= + dependencies: + node-fetch "~1.7.1" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-replace@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" + integrity sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A= + dependencies: + array-back "^1.0.4" + test-value "^2.1.0" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-yarn-workspace-root@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" + integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== + dependencies: + fs-extra "^4.0.3" + micromatch "^3.1.4" + +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flat@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" + integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== + dependencies: + is-buffer "~2.0.3" + +flatted@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +flow-stoplight@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" + integrity sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s= + +fmix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/fmix/-/fmix-0.1.0.tgz#c7bbf124dec42c9d191cfb947d0a9778dd986c0c" + integrity sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw= + dependencies: + imul "^1.0.0" + +follow-redirects@^1.12.1, follow-redirects@^1.14.0: + version "1.14.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" + integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + +for-each@^0.3.3, for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^4.0.2, fs-extra@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +ganache-cli@^6.12.2: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" + integrity sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw== + dependencies: + ethereumjs-util "6.2.1" + source-map-support "0.5.12" + yargs "13.2.4" + +ganache-core@^2.13.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.2.tgz#27e6fc5417c10e6e76e2e646671869d7665814a3" + integrity sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw== + dependencies: + abstract-leveldown "3.0.0" + async "2.6.2" + bip39 "2.5.0" + cachedown "1.0.0" + clone "2.1.2" + debug "3.2.6" + encoding-down "5.0.4" + eth-sig-util "3.0.0" + ethereumjs-abi "0.6.8" + ethereumjs-account "3.0.0" + ethereumjs-block "2.2.2" + ethereumjs-common "1.5.0" + ethereumjs-tx "2.1.2" + ethereumjs-util "6.2.1" + ethereumjs-vm "4.2.0" + heap "0.2.6" + keccak "3.0.1" + level-sublevel "6.6.4" + levelup "3.1.1" + lodash "4.17.20" + lru-cache "5.1.1" + merkle-patricia-tree "3.0.0" + patch-package "6.2.2" + seedrandom "3.0.1" + source-map-support "0.5.12" + tmp "0.1.0" + web3-provider-engine "14.2.1" + websocket "1.0.32" + optionalDependencies: + ethereumjs-wallet "0.6.5" + web3 "1.2.11" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +ghost-testrpc@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" + integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== + dependencies: + chalk "^2.4.2" + node-emoji "^1.10.0" + +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^11.1.0, globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +got@9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +graphql-tag@^2.12.5: + version "2.12.6" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" + integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== + dependencies: + tslib "^2.1.0" + +graphql@^16.3.0: + version "16.3.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.3.0.tgz#a91e24d10babf9e60c706919bb182b53ccdffc05" + integrity sha512-xm+ANmA16BzCT5pLjuXySbQVFwH3oJctUVdy81w1sV0vBU0KgDdBGtxQOUd5zqOBk/JayAFeG8Dlmeq74rjm/A== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +handlebars@^4.0.1: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +hardhat-deploy@^0.10.0: + version "0.10.4" + resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.10.4.tgz#5e064f40f103401ee1e0b8563b6ebf9ad986b921" + integrity sha512-9b7kFWul3Gjm/JURzVicnD5mGNjNyEwFHFKU+8URJ3q4hjCvYR9Ja99ChmVMGzM8DPJhlvEVNBkcv/3wnwZpfQ== + dependencies: + "@ethersproject/abi" "^5.4.0" + "@ethersproject/abstract-signer" "^5.4.1" + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.1" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/contracts" "^5.4.1" + "@ethersproject/providers" "^5.4.4" + "@ethersproject/solidity" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/wallet" "^5.4.0" + "@types/qs" "^6.9.7" + axios "^0.21.1" + chalk "^4.1.2" + chokidar "^3.5.2" + debug "^4.3.2" + enquirer "^2.3.6" + form-data "^4.0.0" + fs-extra "^10.0.0" + match-all "^1.2.6" + murmur-128 "^0.2.1" + qs "^6.9.4" + +hardhat@^2.8.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.8.2.tgz#3afc98866cfa9e7206de6326c8add5d9343ade57" + integrity sha512-cBUqzZGOi+lwKHArWl5Be7zeFIwlu1IUXOna6k5XhORZ8hAWDVbAJBVfxgmjkcX5GffIf0C5g841zRxo36sQ5g== + dependencies: + "@ethereumjs/block" "^3.6.0" + "@ethereumjs/blockchain" "^5.5.0" + "@ethereumjs/common" "^2.6.0" + "@ethereumjs/tx" "^3.4.0" + "@ethereumjs/vm" "^5.6.0" + "@ethersproject/abi" "^5.1.2" + "@sentry/node" "^5.18.1" + "@solidity-parser/parser" "^0.14.0" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + abort-controller "^3.0.0" + adm-zip "^0.4.16" + ansi-escapes "^4.3.0" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + eth-sig-util "^2.5.2" + ethereum-cryptography "^0.1.2" + ethereumjs-abi "^0.6.8" + ethereumjs-util "^7.1.3" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "^7.1.3" + https-proxy-agent "^5.0.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + lodash "^4.17.11" + merkle-patricia-tree "^4.2.2" + mnemonist "^0.38.0" + mocha "^7.2.0" + node-fetch "^2.6.0" + qs "^6.7.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + slash "^3.0.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + "true-case-path" "^2.2.1" + tsort "0.0.1" + uuid "^8.3.2" + ws "^7.4.6" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3, has@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +heap@0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" + integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw= + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +immediate@~3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= + +immutable@^4.0.0-rc.12: + version "4.0.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imul@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9" + integrity sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inquirer@^6.2.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-core-module@^2.2.0, is-core-module@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" + integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= + +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-retry-allowed@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.3, is-typed-array@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" + integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" + foreach "^2.0.5" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-weakref@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +js-sha3@0.5.7, js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= + +js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" + integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== + dependencies: + async "^2.0.1" + babel-preset-env "^1.7.0" + babelify "^7.3.0" + json-rpc-error "^2.0.0" + promise-to-callback "^1.0.0" + safe-event-emitter "^1.0.1" + +json-rpc-engine@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz#75758609d849e1dba1e09021ae473f3ab63161e5" + integrity sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g== + dependencies: + eth-rpc-errors "^3.0.0" + safe-event-emitter "^1.0.1" + +json-rpc-engine@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" + integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + eth-rpc-errors "^4.0.2" + +json-rpc-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" + integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI= + dependencies: + inherits "^2.0.1" + +json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" + integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonschema@^1.2.4: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" + integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +keccak@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +keccak@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" + integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + optionalDependencies: + graceful-fs "^4.1.9" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +level-codec@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" + integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== + dependencies: + buffer "^5.6.0" + +level-codec@~7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" + integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== + +level-concat-iterator@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" + integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== + +level-errors@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" + integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== + dependencies: + errno "~0.1.1" + +level-errors@^2.0.0, level-errors@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== + dependencies: + errno "~0.1.1" + +level-errors@~1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" + integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== + dependencies: + errno "~0.1.1" + +level-iterator-stream@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" + integrity sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.5" + xtend "^4.0.0" + +level-iterator-stream@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" + integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= + dependencies: + inherits "^2.0.1" + level-errors "^1.0.3" + readable-stream "^1.0.33" + xtend "^4.0.0" + +level-iterator-stream@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" + integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.3.6" + xtend "^4.0.0" + +level-iterator-stream@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" + integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== + dependencies: + inherits "^2.0.4" + readable-stream "^3.4.0" + xtend "^4.0.2" + +level-mem@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" + integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== + dependencies: + level-packager "~4.0.0" + memdown "~3.0.0" + +level-mem@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d" + integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg== + dependencies: + level-packager "^5.0.3" + memdown "^5.0.0" + +level-packager@^5.0.3: + version "5.1.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" + integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== + dependencies: + encoding-down "^6.3.0" + levelup "^4.3.2" + +level-packager@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" + integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== + dependencies: + encoding-down "~5.0.0" + levelup "^3.0.0" + +level-post@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" + integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== + dependencies: + ltgt "^2.1.2" + +level-sublevel@6.6.4: + version "6.6.4" + resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" + integrity sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA== + dependencies: + bytewise "~1.1.0" + level-codec "^9.0.0" + level-errors "^2.0.0" + level-iterator-stream "^2.0.3" + ltgt "~2.1.1" + pull-defer "^0.2.2" + pull-level "^2.0.3" + pull-stream "^3.6.8" + typewiselite "~1.0.0" + xtend "~4.0.0" + +level-supports@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" + integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== + dependencies: + xtend "^4.0.2" + +level-ws@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" + integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos= + dependencies: + readable-stream "~1.0.15" + xtend "~2.1.1" + +level-ws@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" + integrity sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q== + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.8" + xtend "^4.0.1" + +level-ws@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" + integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA== + dependencies: + inherits "^2.0.3" + readable-stream "^3.1.0" + xtend "^4.0.1" + +levelup@3.1.1, levelup@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" + integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== + dependencies: + deferred-leveldown "~4.0.0" + level-errors "~2.0.0" + level-iterator-stream "~3.0.0" + xtend "~4.0.0" + +levelup@^1.2.1: + version "1.3.9" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" + integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== + dependencies: + deferred-leveldown "~1.2.1" + level-codec "~7.0.0" + level-errors "~1.0.3" + level-iterator-stream "~1.3.0" + prr "~1.0.1" + semver "~5.4.1" + xtend "~4.0.0" + +levelup@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" + integrity sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ== + dependencies: + deferred-leveldown "~5.3.0" + level-errors "~2.0.0" + level-iterator-stream "~4.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash@4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + +looper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" + integrity sha1-Zs0Md0rz1P7axTeU90LbVtqPCew= + +looper@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" + integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@5.1.1, lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" + integrity sha1-cXibO39Tmb7IVl3aOKow0qCX7+4= + dependencies: + pseudomap "^1.0.1" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= + +ltgt@^2.1.2, ltgt@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= + +ltgt@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" + integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +match-all@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" + integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== + +mcl-wasm@^0.7.1: + version "0.7.9" + resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" + integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memdown@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" + integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= + dependencies: + abstract-leveldown "~2.7.1" + functional-red-black-tree "^1.0.1" + immediate "^3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.1.1" + +memdown@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" + integrity sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw== + dependencies: + abstract-leveldown "~6.2.1" + functional-red-black-tree "~1.0.1" + immediate "~3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.2.0" + +memdown@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" + integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== + dependencies: + abstract-leveldown "~5.0.0" + functional-red-black-tree "~1.0.1" + immediate "~3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.1.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge2@^1.2.3, merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +merkle-patricia-tree@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" + integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== + dependencies: + async "^2.6.1" + ethereumjs-util "^5.2.0" + level-mem "^3.0.1" + level-ws "^1.0.0" + readable-stream "^3.0.6" + rlp "^2.0.0" + semaphore ">=1.0.1" + +merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" + integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== + dependencies: + async "^1.4.2" + ethereumjs-util "^5.0.0" + level-ws "0.0.0" + levelup "^1.2.1" + memdown "^1.0.0" + readable-stream "^2.0.0" + rlp "^2.0.0" + semaphore ">=1.0.1" + +merkle-patricia-tree@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz#6dec17855370172458244c2f42c989dd60b773a3" + integrity sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q== + dependencies: + "@types/levelup" "^4.3.0" + ethereumjs-util "^7.1.2" + level-mem "^5.0.1" + level-ws "^2.0.0" + readable-stream "^3.6.0" + rlp "^2.2.4" + semaphore-async-await "^1.5.1" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= + dependencies: + mkdirp "*" + +mkdirp@*, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@0.5.5, mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mnemonist@^0.38.0: + version "0.38.5" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" + integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== + dependencies: + obliterator "^2.0.0" + +mocha@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" + integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== + dependencies: + ansi-colors "3.2.3" + browser-stdout "1.3.1" + chokidar "3.3.0" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + find-up "3.0.0" + glob "7.1.3" + growl "1.10.5" + he "1.2.0" + js-yaml "3.13.1" + log-symbols "3.0.0" + minimatch "3.0.4" + mkdirp "0.5.5" + ms "2.1.1" + node-environment-flags "1.0.6" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.3.2" + yargs-parser "13.1.2" + yargs-unparser "1.6.0" + +mock-fs@^4.1.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" + integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^0.5.5: + version "0.5.7" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== + dependencies: + varint "^5.0.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + +multihashes@^0.4.15, multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + +murmur-128@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" + integrity sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg== + dependencies: + encode-utf8 "^1.0.2" + fmix "^0.1.0" + imul "^1.0.0" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-emoji@^1.10.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== + dependencies: + lodash "^4.17.21" + +node-environment-flags@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + +node-fetch@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-fetch@^2.6.0, node-fetch@^2.6.1: + version "2.6.6" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" + integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@~1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + +nofilter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" + integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== + +noms@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859" + integrity sha1-2o69nzr51nYJGbJ9nNyAkqczKFk= + dependencies: + inherits "^2.0.1" + readable-stream "~1.0.31" + +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-scripts-info@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/npm-scripts-info/-/npm-scripts-info-0.3.9.tgz#464e4178218e454564adca7ba71925bc71a4973d" + integrity sha512-r3kftwUxThTxQoZ+RoR8xVIL1FOmqpCM6+7BH6jR4HPdigNbBs9Bg1nt3Qrqn2b8jj4NrE69+kWE3EkmNxkmkg== + dependencies: + chalk "^2.3.0" + meow "^4.0.0" + unquote "^1.1.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.0.0, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-inspect@~1.11.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b" + integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" + integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +obliterator@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.1.tgz#fbdd873bf39fc4f365a53b1fc86617a22526987c" + integrity sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w== + +oboe@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" + integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= + dependencies: + http-https "^1.0.0" + +oboe@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" + integrity sha1-VVQoTFQ6ImbXo48X4HOCH73jk80= + dependencies: + http-https "^1.0.0" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +open@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-headers@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.4.tgz#9eaf2d02bed2d1eff494331ce3df36d7924760bf" + integrity sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +patch-package@6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" + integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^2.4.2" + cross-spawn "^6.0.5" + find-yarn-workspace-root "^1.2.1" + fs-extra "^7.0.1" + is-ci "^2.0.0" + klaw-sync "^6.0.0" + minimist "^1.2.0" + rimraf "^2.6.3" + semver "^5.6.0" + slash "^2.0.0" + tmp "^0.0.33" + +patch-package@^6.2.2: + version "6.4.7" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148" + integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^2.4.2" + cross-spawn "^6.0.5" + find-yarn-workspace-root "^2.0.0" + fs-extra "^7.0.1" + is-ci "^2.0.0" + klaw-sync "^6.0.0" + minimist "^1.2.0" + open "^7.4.2" + rimraf "^2.6.3" + semver "^5.6.0" + slash "^2.0.0" + tmp "^0.0.33" + +path-browserify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postinstall-postinstall@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" + integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== + +precond@0.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" + integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier-plugin-solidity@^1.0.0-beta.19: + version "1.0.0-beta.19" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz#7c3607fc4028f5e6a425259ff03e45eedf733df3" + integrity sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g== + dependencies: + "@solidity-parser/parser" "^0.14.0" + emoji-regex "^10.0.0" + escape-string-regexp "^4.0.0" + semver "^7.3.5" + solidity-comments-extractor "^0.0.7" + string-width "^4.2.3" + +prettier@^1.14.3: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +prettier@^2.1.2, prettier@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== + +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-to-callback@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" + integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc= + dependencies: + is-fn "^1.0.0" + set-immediate-shim "^1.0.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pull-cat@^1.1.9: + version "1.1.11" + resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" + integrity sha1-tkLdElXaN2pwa220+pYvX9t0wxs= + +pull-defer@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" + integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== + +pull-level@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" + integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== + dependencies: + level-post "^1.0.7" + pull-cat "^1.1.9" + pull-live "^1.0.1" + pull-pushable "^2.0.0" + pull-stream "^3.4.0" + pull-window "^2.1.4" + stream-to-pull-stream "^1.7.1" + +pull-live@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" + integrity sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU= + dependencies: + pull-cat "^1.1.9" + pull-stream "^3.4.0" + +pull-pushable@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" + integrity sha1-Xy867UethpGfAbEqLpnW8b13ZYE= + +pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: + version "3.6.14" + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" + integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew== + +pull-window@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" + integrity sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA= + dependencies: + looper "^2.0.0" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +qs@^6.7.0, qs@^6.9.4: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2, raw-body@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +readable-stream@^1.0.33: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.0.15, readable-stream@~1.0.31: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" + integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== + dependencies: + picomatch "^2.0.4" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +recursive-readdir@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + +regenerate@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request@^2.79.0, request@^2.85.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= + +require-from-string@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.8.1: + version "1.21.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" + integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA== + dependencies: + is-core-module "^2.8.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@~1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= + dependencies: + through "~2.3.4" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.2.8, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4: + version "2.2.7" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== + dependencies: + bn.js "^5.2.0" + +run-async@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rustbn.js@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" + integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== + +rxjs@^6.4.0: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-event-emitter@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" + integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== + dependencies: + events "^3.0.0" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sc-istanbul@^0.4.5: + version "0.4.6" + resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" + integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g== + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +scrypt-js@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" + integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== + +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +scryptsy@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= + dependencies: + pbkdf2 "^3.0.3" + +secp256k1@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +seedrandom@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" + integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg== + +semaphore-async-await@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" + integrity sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo= + +semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" + integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.4, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@~5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@^1.6.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + +shelljs@^0.8.3: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^2.7.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +solc@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" + integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== + dependencies: + command-exists "^1.2.8" + commander "3.0.2" + follow-redirects "^1.12.1" + fs-extra "^0.30.0" + js-sha3 "0.8.0" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + +solc@^0.4.20: + version "0.4.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== + dependencies: + fs-extra "^0.30.0" + memorystream "^0.3.1" + require-from-string "^1.1.0" + semver "^5.3.0" + yargs "^4.7.1" + +solc@^0.6.3: + version "0.6.12" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.12.tgz#48ac854e0c729361b22a7483645077f58cba080e" + integrity sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g== + dependencies: + command-exists "^1.2.8" + commander "3.0.2" + fs-extra "^0.30.0" + js-sha3 "0.8.0" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + +solhint-plugin-prettier@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz#e3b22800ba435cd640a9eca805a7f8bc3e3e6a6b" + integrity sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA== + dependencies: + prettier-linter-helpers "^1.0.0" + +solhint@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.6.tgz#abe9af185a9a7defefba480047b3e42cbe9a1210" + integrity sha512-HWUxTAv2h7hx3s3hAab3ifnlwb02ZWhwFU/wSudUHqteMS3ll9c+m1FlGn9V8ztE2rf3Z82fQZA005Wv7KpcFA== + dependencies: + "@solidity-parser/parser" "^0.13.2" + ajv "^6.6.1" + antlr4 "4.7.1" + ast-parents "0.0.1" + chalk "^2.4.2" + commander "2.18.0" + cosmiconfig "^5.0.7" + eslint "^5.6.0" + fast-diff "^1.1.2" + glob "^7.1.3" + ignore "^4.0.6" + js-yaml "^3.12.0" + lodash "^4.17.11" + semver "^6.3.0" + optionalDependencies: + prettier "^1.14.3" + +solidity-bytes-utils@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/solidity-bytes-utils/-/solidity-bytes-utils-0.8.0.tgz#9d985a3c4aee68fbd532a9a065edade1c132442f" + integrity sha512-r109ZHEf7zTMm1ENW6/IJFDWilFR/v0BZnGuFgDHJUV80ByobnV2k3txvwQaJ9ApL+6XAfwqsw5VFzjALbQPCw== + dependencies: + "@truffle/hdwallet-provider" latest + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +solidity-coverage@^0.7.17: + version "0.7.17" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.7.17.tgz#5139de8f6666d4755d88f453d8e35632a7bb3444" + integrity sha512-Erw2hd2xdACAvDX8jUdYkmgJlIIazGznwDJA5dhRaw4def2SisXN9jUjneeyOZnl/E7j6D3XJYug4Zg9iwodsg== + dependencies: + "@solidity-parser/parser" "^0.13.2" + "@truffle/provider" "^0.2.24" + chalk "^2.4.2" + death "^1.1.0" + detect-port "^1.3.0" + fs-extra "^8.1.0" + ganache-cli "^6.12.2" + ghost-testrpc "^0.0.2" + global-modules "^2.0.0" + globby "^10.0.1" + jsonschema "^1.2.4" + lodash "^4.17.15" + node-emoji "^1.10.0" + pify "^4.0.1" + recursive-readdir "^2.2.2" + sc-istanbul "^0.4.5" + semver "^7.3.4" + shelljs "^0.8.3" + web3-utils "^1.3.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@0.5.12: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.13: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stacktrace-parser@^0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-to-pull-stream@^1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" + integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== + dependencies: + looper "^3.0.0" + pull-stream "^3.2.3" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.padend@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" + integrity sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +string.prototype.trim@~1.2.4: + version "1.2.5" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.5.tgz#a587bcc8bfad8cb9829a577f5de30dd170c1682c" + integrity sha512-Lnh17webJVsD6ECeovpVN17RlAKjmz4rF9S+8Y45CkMc/ufVpTkU3vZIyIC7sllQ1FCvObZnnCdNs/HXTUOTlg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= + dependencies: + is-hex-prefixed "1.0.0" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@2.0.1, strip-json-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== + dependencies: + has-flag "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +swarm-js@^0.1.40: + version "0.1.40" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99" + integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^7.1.0" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request "^1.0.1" + +table-layout@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tape@^4.6.3: + version "4.14.0" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.14.0.tgz#e4d46097e129817175b90925f2385f6b1bcfa826" + integrity sha512-z0+WrUUJuG6wIdWrl4W3rTte2CR26G6qcPOj3w1hfRdcmhF3kHBhOBW9VHsPVAkz08ZmGzp7phVpDupbLzrYKQ== + dependencies: + call-bind "~1.0.2" + deep-equal "~1.1.1" + defined "~1.0.0" + dotignore "~0.1.2" + for-each "~0.3.3" + glob "~7.1.7" + has "~1.0.3" + inherits "~2.0.4" + is-regex "~1.1.3" + minimist "~1.2.5" + object-inspect "~1.11.0" + resolve "~1.20.0" + resumer "~0.0.0" + string.prototype.trim "~1.2.4" + through "~2.3.8" + +tar@^4.0.2: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + +test-value@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" + integrity sha1-Edpv9nDzRxpztiXKTz/c97t0gpE= + dependencies: + array-back "^1.0.3" + typical "^2.6.0" + +testrpc@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^2.0.1, through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6, through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +tmp@0.0.33, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== + dependencies: + rimraf "^2.6.3" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +"true-case-path@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" + integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q== + +ts-command-line-args@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.2.0.tgz#655e10451b06c86d318e9467546da4d19b773a55" + integrity sha512-RedEejZyhiEAOgBkIVxB4QC/SRYtl98D7b7epWB9e6E+TmK8KstXBu3WdnhGbMHicLkHoG7sCAmu+F+ASzLFHA== + dependencies: + chalk "^4.1.0" + command-line-args "^5.1.1" + command-line-usage "^6.1.0" + string-format "^2.0.0" + +ts-essentials@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" + integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== + +ts-essentials@^6.0.3: + version "6.0.7" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-6.0.7.tgz#5f4880911b7581a873783740ce8b94da163d18a6" + integrity sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw== + +ts-essentials@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== + +ts-generator@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" + integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== + dependencies: + "@types/mkdirp" "^0.5.2" + "@types/prettier" "^2.1.1" + "@types/resolve" "^0.0.8" + chalk "^2.4.1" + glob "^7.1.2" + mkdirp "^0.5.1" + prettier "^2.1.2" + resolve "^1.8.1" + ts-essentials "^1.0.0" + +ts-node@^10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" + integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + yn "3.1.1" + +tslib@^1.9.0, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl-util@^0.15.0: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +tweetnacl@^1.0.0, tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + +typechain@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-3.0.0.tgz#d5a47700831f238e43f7429b987b4bb54849b92e" + integrity sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg== + dependencies: + command-line-args "^4.0.7" + debug "^4.1.1" + fs-extra "^7.0.0" + js-sha3 "^0.8.0" + lodash "^4.17.15" + ts-essentials "^6.0.3" + ts-generator "^0.1.1" + +typechain@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-6.1.0.tgz#462a35f555accf870689d1ba5698749108d0ce81" + integrity sha512-GGfkK0p3fUgz8kYxjSS4nKcWXE0Lo+teHTetghousIK5njbNoYNDlwn91QIyD181L3fVqlTvBE0a/q3AZmjNfw== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.1.1" + fs-extra "^7.0.0" + glob "^7.1.6" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.1.2" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" + integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== + +typewise-core@^1.2, typewise-core@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" + integrity sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU= + +typewise@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" + integrity sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE= + dependencies: + typewise-core "^1.2.0" + +typewiselite@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" + integrity sha1-yIgvobsQksBgBal/NO9chQjjZk4= + +typical@^2.6.0, typical@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" + integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0= + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +uglify-js@^3.1.4: + version "3.14.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.5.tgz#cdabb7d4954231d80cb4a927654c4655e51f4859" + integrity sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ== + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +underscore@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unorm@^1.3.3: + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +utf-8-validate@^5.0.2: + version "5.0.8" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.8.tgz#4a735a61661dbb1c59a0868c397d2fe263f14e58" + integrity sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA== + dependencies: + node-gyp-build "^4.3.0" + +utf8@3.0.0, utf8@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + for-each "^0.3.3" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.1" + +util@^0.12.0: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" + integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= + +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +web3-bzz@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" + integrity sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg== + dependencies: + "@types/node" "^12.12.6" + got "9.6.0" + swarm-js "^0.1.40" + underscore "1.9.1" + +web3-bzz@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.5.3.tgz#e36456905ce051138f9c3ce3623cbc73da088c2b" + integrity sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg== + dependencies: + "@types/node" "^12.12.6" + got "9.6.0" + swarm-js "^0.1.40" + +web3-core-helpers@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99" + integrity sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A== + dependencies: + underscore "1.9.1" + web3-eth-iban "1.2.11" + web3-utils "1.2.11" + +web3-core-helpers@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz#099030235c477aadf39a94199ef40092151d563c" + integrity sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw== + dependencies: + web3-eth-iban "1.5.3" + web3-utils "1.5.3" + +web3-core-method@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6" + integrity sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw== + dependencies: + "@ethersproject/transactions" "^5.0.0-beta.135" + underscore "1.9.1" + web3-core-helpers "1.2.11" + web3-core-promievent "1.2.11" + web3-core-subscriptions "1.2.11" + web3-utils "1.2.11" + +web3-core-method@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.5.3.tgz#6cff97ed19fe4ea2e9183d6f703823a079f5132c" + integrity sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg== + dependencies: + "@ethereumjs/common" "^2.4.0" + "@ethersproject/transactions" "^5.0.0-beta.135" + web3-core-helpers "1.5.3" + web3-core-promievent "1.5.3" + web3-core-subscriptions "1.5.3" + web3-utils "1.5.3" + +web3-core-promievent@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf" + integrity sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA== + dependencies: + eventemitter3 "4.0.4" + +web3-core-promievent@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz#3f11833c3dc6495577c274350b61144e0a4dba01" + integrity sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a" + integrity sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.11" + web3-providers-http "1.2.11" + web3-providers-ipc "1.2.11" + web3-providers-ws "1.2.11" + +web3-core-requestmanager@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz#b339525815fd40e3a2a81813c864ddc413f7b6f7" + integrity sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg== + dependencies: + util "^0.12.0" + web3-core-helpers "1.5.3" + web3-providers-http "1.5.3" + web3-providers-ipc "1.5.3" + web3-providers-ws "1.5.3" + +web3-core-subscriptions@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd" + integrity sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg== + dependencies: + eventemitter3 "4.0.4" + underscore "1.9.1" + web3-core-helpers "1.2.11" + +web3-core-subscriptions@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz#d7d69c4caad65074212028656e9dc56ca5c2159d" + integrity sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.5.3" + +web3-core@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7" + integrity sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ== + dependencies: + "@types/bn.js" "^4.11.5" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-requestmanager "1.2.11" + web3-utils "1.2.11" + +web3-core@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.5.3.tgz#59f8728b27c8305b349051326aa262b9b7e907bf" + integrity sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ== + dependencies: + "@types/bn.js" "^4.11.5" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-core-requestmanager "1.5.3" + web3-utils "1.5.3" + +web3-eth-abi@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0" + integrity sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg== + dependencies: + "@ethersproject/abi" "5.0.0-beta.153" + underscore "1.9.1" + web3-utils "1.2.11" + +web3-eth-abi@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz#5aea9394d797f99ca0d9bd40c3417eb07241c96c" + integrity sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg== + dependencies: + "@ethersproject/abi" "5.0.7" + web3-utils "1.5.3" + +web3-eth-accounts@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520" + integrity sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw== + dependencies: + crypto-browserify "3.12.0" + eth-lib "0.2.8" + ethereumjs-common "^1.3.2" + ethereumjs-tx "^2.1.1" + scrypt-js "^3.0.1" + underscore "1.9.1" + uuid "3.3.2" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-utils "1.2.11" + +web3-eth-accounts@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz#076c816ff4d68c9dffebdc7fd2bfaddcfc163d77" + integrity sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw== + dependencies: + "@ethereumjs/common" "^2.3.0" + "@ethereumjs/tx" "^3.2.1" + crypto-browserify "3.12.0" + eth-lib "0.2.8" + ethereumjs-util "^7.0.10" + scrypt-js "^3.0.1" + uuid "3.3.2" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-utils "1.5.3" + +web3-eth-contract@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90" + integrity sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow== + dependencies: + "@types/bn.js" "^4.11.5" + underscore "1.9.1" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-promievent "1.2.11" + web3-core-subscriptions "1.2.11" + web3-eth-abi "1.2.11" + web3-utils "1.2.11" + +web3-eth-contract@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz#12b03a4a16ce583a945f874bea2ff2fb4c5b81ad" + integrity sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg== + dependencies: + "@types/bn.js" "^4.11.5" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-core-promievent "1.5.3" + web3-core-subscriptions "1.5.3" + web3-eth-abi "1.5.3" + web3-utils "1.5.3" + +web3-eth-ens@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532" + integrity sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + underscore "1.9.1" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-promievent "1.2.11" + web3-eth-abi "1.2.11" + web3-eth-contract "1.2.11" + web3-utils "1.2.11" + +web3-eth-ens@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz#ef6eee1ddf32b1ff9536fc7c599a74f2656bafe1" + integrity sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-promievent "1.5.3" + web3-eth-abi "1.5.3" + web3-eth-contract "1.5.3" + web3-utils "1.5.3" + +web3-eth-iban@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef" + integrity sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ== + dependencies: + bn.js "^4.11.9" + web3-utils "1.2.11" + +web3-eth-iban@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz#91b1475893a877b10eac1de5cce6eb379fb81b5d" + integrity sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw== + dependencies: + bn.js "^4.11.9" + web3-utils "1.5.3" + +web3-eth-personal@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70" + integrity sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-net "1.2.11" + web3-utils "1.2.11" + +web3-eth-personal@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz#4ebe09e9a77dd49d23d93b36b36cfbf4a6dae713" + integrity sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-net "1.5.3" + web3-utils "1.5.3" + +web3-eth@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793" + integrity sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ== + dependencies: + underscore "1.9.1" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-subscriptions "1.2.11" + web3-eth-abi "1.2.11" + web3-eth-accounts "1.2.11" + web3-eth-contract "1.2.11" + web3-eth-ens "1.2.11" + web3-eth-iban "1.2.11" + web3-eth-personal "1.2.11" + web3-net "1.2.11" + web3-utils "1.2.11" + +web3-eth@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.5.3.tgz#d7d1ac7198f816ab8a2088c01e0bf1eda45862fe" + integrity sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q== + dependencies: + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-core-subscriptions "1.5.3" + web3-eth-abi "1.5.3" + web3-eth-accounts "1.5.3" + web3-eth-contract "1.5.3" + web3-eth-ens "1.5.3" + web3-eth-iban "1.5.3" + web3-eth-personal "1.5.3" + web3-net "1.5.3" + web3-utils "1.5.3" + +web3-net@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b" + integrity sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg== + dependencies: + web3-core "1.2.11" + web3-core-method "1.2.11" + web3-utils "1.2.11" + +web3-net@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.5.3.tgz#545fee49b8e213b0c55cbe74ffd0295766057463" + integrity sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ== + dependencies: + web3-core "1.5.3" + web3-core-method "1.5.3" + web3-utils "1.5.3" + +web3-provider-engine@14.2.1: + version "14.2.1" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" + integrity sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw== + dependencies: + async "^2.5.0" + backoff "^2.5.0" + clone "^2.0.0" + cross-fetch "^2.1.0" + eth-block-tracker "^3.0.0" + eth-json-rpc-infura "^3.1.0" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.2.2" + ethereumjs-tx "^1.2.0" + ethereumjs-util "^5.1.5" + ethereumjs-vm "^2.3.4" + json-rpc-error "^2.0.0" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + readable-stream "^2.2.9" + request "^2.85.0" + semaphore "^1.0.3" + ws "^5.1.1" + xhr "^2.2.0" + xtend "^4.0.1" + +web3-provider-engine@16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-16.0.3.tgz#8ff93edf3a8da2f70d7f85c5116028c06a0d9f07" + integrity sha512-Q3bKhGqLfMTdLvkd4TtkGYJHcoVQ82D1l8jTIwwuJp/sAp7VHnRYb9YJ14SW/69VMWoOhSpPLZV2tWb9V0WJoA== + dependencies: + "@ethereumjs/tx" "^3.3.0" + async "^2.5.0" + backoff "^2.5.0" + clone "^2.0.0" + cross-fetch "^2.1.0" + eth-block-tracker "^4.4.2" + eth-json-rpc-filters "^4.2.1" + eth-json-rpc-infura "^5.1.0" + eth-json-rpc-middleware "^6.0.0" + eth-rpc-errors "^3.0.0" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.2.2" + ethereumjs-util "^5.1.5" + ethereumjs-vm "^2.3.4" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + readable-stream "^2.2.9" + request "^2.85.0" + semaphore "^1.0.3" + ws "^5.1.1" + xhr "^2.2.0" + xtend "^4.0.1" + +web3-providers-http@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6" + integrity sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA== + dependencies: + web3-core-helpers "1.2.11" + xhr2-cookies "1.1.0" + +web3-providers-http@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.5.3.tgz#74f170fc3d79eb7941d9fbc34e2a067d61ced0b2" + integrity sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw== + dependencies: + web3-core-helpers "1.5.3" + xhr2-cookies "1.1.0" + +web3-providers-ipc@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21" + integrity sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ== + dependencies: + oboe "2.1.4" + underscore "1.9.1" + web3-core-helpers "1.2.11" + +web3-providers-ipc@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz#4bd7f5e445c2f3c2595fce0929c72bb879320a3f" + integrity sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.5.3" + +web3-providers-ws@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb" + integrity sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg== + dependencies: + eventemitter3 "4.0.4" + underscore "1.9.1" + web3-core-helpers "1.2.11" + websocket "^1.0.31" + +web3-providers-ws@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz#eec6cfb32bb928a4106de506f13a49070a21eabf" + integrity sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.5.3" + websocket "^1.0.32" + +web3-shh@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f" + integrity sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg== + dependencies: + web3-core "1.2.11" + web3-core-method "1.2.11" + web3-core-subscriptions "1.2.11" + web3-net "1.2.11" + +web3-shh@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.5.3.tgz#3c04aa4cda9ba0b746d7225262401160f8e38b13" + integrity sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q== + dependencies: + web3-core "1.5.3" + web3-core-method "1.5.3" + web3-core-subscriptions "1.5.3" + web3-net "1.5.3" + +web3-utils@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82" + integrity sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ== + dependencies: + bn.js "^4.11.9" + eth-lib "0.2.8" + ethereum-bloom-filters "^1.0.6" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + underscore "1.9.1" + utf8 "3.0.0" + +web3-utils@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.5.3.tgz#e914c9320cd663b2a09a5cb920ede574043eb437" + integrity sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q== + dependencies: + bn.js "^4.11.9" + eth-lib "0.2.8" + ethereum-bloom-filters "^1.0.6" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3-utils@^1.0.0-beta.31, web3-utils@^1.3.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.6.1.tgz#befcb23922b00603ab56d8c5b4158468dc494aca" + integrity sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w== + dependencies: + bn.js "^4.11.9" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" + integrity sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ== + dependencies: + web3-bzz "1.2.11" + web3-core "1.2.11" + web3-eth "1.2.11" + web3-eth-personal "1.2.11" + web3-net "1.2.11" + web3-shh "1.2.11" + web3-utils "1.2.11" + +web3@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.5.3.tgz#11882679453c645bf33620fbc255a243343075aa" + integrity sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w== + dependencies: + web3-bzz "1.5.3" + web3-core "1.5.3" + web3-eth "1.5.3" + web3-eth-personal "1.5.3" + web3-net "1.5.3" + web3-shh "1.5.3" + web3-utils "1.5.3" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + +websocket@1.0.32: + version "1.0.32" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" + integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +websocket@^1.0.31, websocket@^1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-typed-array@^1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" + integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" + foreach "^2.0.5" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.7" + +which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= + +wonka@^4.0.14: + version "4.0.15" + resolved "https://registry.yarnpkg.com/wonka/-/wonka-4.0.15.tgz#9aa42046efa424565ab8f8f451fcca955bf80b89" + integrity sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg== + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@^5.1.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" + integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== + dependencies: + async-limiter "~1.0.0" + +ws@^7.4.6: + version "7.5.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" + integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== + +xhr-request-promise@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== + dependencies: + xhr-request "^1.1.0" + +xhr-request@^1.0.1, xhr-request@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= + dependencies: + cookiejar "^2.1.1" + +xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== + dependencies: + global "~4.4.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xmlhttprequest@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= + +xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= + dependencies: + object-keys "~0.4.0" + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@13.1.2, yargs-parser@^13.1.0, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" + integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== + dependencies: + flat "^4.1.0" + lodash "^4.17.15" + yargs "^13.3.0" + +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" + +yargs@13.3.2, yargs@^13.3.0: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^16.1.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA= + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== diff --git a/php-basic-crud/docker-compose-host.yml b/php-basic-crud/docker-compose-host.yml new file mode 100644 index 00000000..ac3c91b9 --- /dev/null +++ b/php-basic-crud/docker-compose-host.yml @@ -0,0 +1,124 @@ +version: '3' + +services: + hardhat: + container_name: php-basic-crud-hardhat + build: ./contracts + command: ["node", "--write", "true", "--network", "hardhat", "--export", "/opt/cartesi/share/blockchain/localhost.json"] + platform: linux/amd64 + init: true + ports: + - '8545:8545' + volumes: + - ./contracts/export/abi:/opt/cartesi/share/blockchain + + rollups_dispatcher: + depends_on: [hardhat] + image: cartesi/rollups-dispatcher:0.1.2 + restart: always + platform: linux/amd64 + environment: + # TODO: currently hardhat's default mnemonic + # this should become a secret + - MNEMONIC=test test test test test test test test test test test junk + - CHAIN_ID=31337 + - RUST_LOG=info + - LOGIC_CONFIG_PATH=/opt/cartesi/share/config/logic-config.toml + - STATE_FOLD_CONFIG_PATH=/opt/cartesi/share/config/sf-config.toml + - BLOCK_SUBSCRIBER_CONFIG_PATH=/opt/cartesi/share/config/bs-config.toml + - TX_MANAGER_CONFIG_PATH=/opt/cartesi/share/config/tm-config.toml + - STATE_SERVER_HOSTNAME=state_server + - STATE_SERVER_PORT=50051 + - SERVER_MANAGER_HOSTNAME=server_manager + - SERVER_MANAGER_PORT=5001 + - DEPLOYMENT_PATH=/opt/cartesi/share/blockchain/localhost.json + volumes: + - ./contracts/export/abi:/opt/cartesi/share/blockchain:ro + - ./config:/opt/cartesi/share/config/ + + state_server: + depends_on: [hardhat] + image: cartesi/delegate-server:0.1.2 + restart: always + platform: linux/amd64 + environment: + - STATE_FOLD_CONFIG_PATH=/opt/cartesi/share/config/sf-config.toml + - DEPLOYMENT_PATH=/opt/cartesi/share/blockchain/localhost.json + - URL=http://hardhat:8545 + volumes: + - ./contracts/export/abi:/opt/cartesi/share/blockchain:ro + - ./config:/opt/cartesi/share/config/ + + server_manager: + image: cartesi/host-server-manager:0.2.1 + platform: linux/amd64 + environment: + - DAPP_HTTP_ADDRESS=host.docker.internal + ports: + - "5004:5004" + restart: always + extra_hosts: + - "host.docker.internal:host-gateway" + + rollups_indexer: + depends_on: [hardhat] + image: cartesi/rollups-indexer:0.1.2 + restart: always + platform: linux/amd64 + environment: + - URL=http://hardhat:8545 + - INDEXER_CONFIG_PATH=/opt/cartesi/share/config/indexer-config.toml + - STATE_SERVER_HOSTNAME=state_server + - STATE_SERVER_PORT=50051 + - SERVER_MANAGER_HOSTNAME=server_manager + - SERVER_MANAGER_PORT=5001 + - DEPLOYMENT_PATH=/opt/cartesi/share/blockchain/localhost.json + - POSTGRES_HOSTNAME=database + - POSTGRES_PORT=5432 + volumes: + - ./contracts/export/abi:/opt/cartesi/share/blockchain + - ./config:/opt/cartesi/share/config/ + + query_server: + image: cartesi/query-server:0.1.2 + platform: linux/amd64 + ports: + - '4000:4000' + links: + - database + depends_on: + - database + environment: + - DB_USER=postgres + - DB_NAME=postgres + - DB_PASSWORD=password + - DB_HOST=database + - DB_TEST_NAME=postgres + - URL=http://hardhat:8545 + + database: + image: postgres:12 + platform: linux/amd64 + ports: + - 5432:5432 + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=password + volumes: + - database-data:/var/lib/postgresql/data + + provy_server: + depends_on: + - hardhat + links: + - hardhat + ports: + - '8000:8000' + build: ./proxy + working_dir: /var/www/ + volumes: + - ./proxy:/var/www + - /var/run/docker.sock:/var/run/docker.sock + +volumes: + database-data: {} diff --git a/php-basic-crud/docker-compose.yml b/php-basic-crud/docker-compose.yml new file mode 100644 index 00000000..2f76efda --- /dev/null +++ b/php-basic-crud/docker-compose.yml @@ -0,0 +1,121 @@ +version: '3' + +services: + hardhat: + container_name: php-basic-crud-hardhat + build: ./contracts + command: ["node", "--write", "true", "--network", "hardhat", "--export", "/opt/cartesi/share/blockchain/localhost.json"] + init: true + ports: + - '8545:8545' + platform: linux/amd64 + volumes: + - blockchain-data:/opt/cartesi/share/blockchain + - ./contracts/deployments:/app/deployments + + rollups_dispatcher: + depends_on: [hardhat] + image: cartesi/rollups-dispatcher:0.1.3 + platform: linux/amd64 + restart: always + environment: + # TODO: currently hardhat's default mnemonic + # this should become a secret + - MNEMONIC=test test test test test test test test test test test junk + - CHAIN_ID=31337 + - RUST_LOG=info + - LOGIC_CONFIG_PATH=/opt/cartesi/share/config/logic-config.toml + - STATE_FOLD_CONFIG_PATH=/opt/cartesi/share/config/sf-config.toml + - BLOCK_SUBSCRIBER_CONFIG_PATH=/opt/cartesi/share/config/bs-config.toml + - TX_MANAGER_CONFIG_PATH=/opt/cartesi/share/config/tm-config.toml + - STATE_SERVER_HOSTNAME=state_server + - STATE_SERVER_PORT=50051 + - SERVER_MANAGER_HOSTNAME=server_manager + - SERVER_MANAGER_PORT=5001 + - DEPLOYMENT_PATH=/opt/cartesi/share/blockchain/localhost.json + volumes: + - blockchain-data:/opt/cartesi/share/blockchain:ro + - ./config:/opt/cartesi/share/config/ + + state_server: + depends_on: [hardhat] + image: cartesi/delegate-server:0.1.3 + platform: linux/amd64 + restart: always + environment: + - STATE_FOLD_CONFIG_PATH=/opt/cartesi/share/config/sf-config.toml + - DEPLOYMENT_PATH=/opt/cartesi/share/blockchain/localhost.json + - URL=http://hardhat:8545 + volumes: + - blockchain-data:/opt/cartesi/share/blockchain:ro + - ./config:/opt/cartesi/share/config/ + + server_manager: + image: cartesi/server-manager:0.1.0 + platform: linux/amd64 + restart: always + volumes: + - ./machine:/opt/cartesi/share/dapp-bin + + rollups_indexer: + depends_on: [hardhat] + image: cartesi/rollups-indexer:0.1.3 + platform: linux/amd64 + restart: always + environment: + - URL=http://hardhat:8545 + - INDEXER_CONFIG_PATH=/opt/cartesi/share/config/indexer-config.toml + - STATE_SERVER_HOSTNAME=state_server + - STATE_SERVER_PORT=50051 + - SERVER_MANAGER_HOSTNAME=server_manager + - SERVER_MANAGER_PORT=5001 + - DEPLOYMENT_PATH=/opt/cartesi/share/blockchain/localhost.json + - POSTGRES_HOSTNAME=database + - POSTGRES_PORT=5432 + volumes: + - blockchain-data:/opt/cartesi/share/blockchain + - ./config:/opt/cartesi/share/config/ + + query_server: + image: cartesi/query-server:0.1.3 + platform: linux/amd64 + ports: + - '4000:4000' + links: + - database + depends_on: + - database + environment: + - DB_USER=postgres + - DB_NAME=postgres + - DB_PASSWORD=password + - DB_HOST=database + - DB_TEST_NAME=postgres + + database: + image: postgres:12 + platform: linux/amd64 + ports: + - 5432:5432 + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=password + volumes: + - database-data:/var/lib/postgresql/data + + provy_server: + depends_on: + - hardhat + links: + - hardhat + ports: + - '8000:8000' + build: ./proxy + working_dir: /var/www/ + volumes: + - ./proxy:/var/www + - /var/run/docker.sock:/var/run/docker.sock + +volumes: + blockchain-data: {} + database-data: {} diff --git a/php-basic-crud/proxy/.gitignore b/php-basic-crud/proxy/.gitignore new file mode 100644 index 00000000..a402e6cb --- /dev/null +++ b/php-basic-crud/proxy/.gitignore @@ -0,0 +1,3 @@ +/vendor +/.idea +/storage diff --git a/php-basic-crud/proxy/Dockerfile b/php-basic-crud/proxy/Dockerfile new file mode 100644 index 00000000..49df09e7 --- /dev/null +++ b/php-basic-crud/proxy/Dockerfile @@ -0,0 +1,22 @@ +FROM php:8.1.0-fpm + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + git \ + curl \ + libpng-dev \ + libonig-dev \ + libxml2-dev \ + zip \ + unzip \ + docker.io + +RUN docker-php-ext-install bcmath + +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +CMD composer install --no-interaction --no-scripts --prefer-dist && php -S 0.0.0.0:8000 -t public + +WORKDIR /var/www + +EXPOSE 8000 diff --git a/php-basic-crud/proxy/README.md b/php-basic-crud/proxy/README.md new file mode 100644 index 00000000..cd065846 --- /dev/null +++ b/php-basic-crud/proxy/README.md @@ -0,0 +1 @@ +# Cartesi Rollup proxy based on Lumen PHP Framework diff --git a/php-basic-crud/proxy/composer.json b/php-basic-crud/proxy/composer.json new file mode 100644 index 00000000..c29b5ac9 --- /dev/null +++ b/php-basic-crud/proxy/composer.json @@ -0,0 +1,23 @@ +{ + "name": "laravel/lumen", + "description": "The Laravel Lumen Framework.", + "keywords": ["framework", "laravel", "lumen"], + "license": "MIT", + "type": "project", + "require": { + "php": "^8.0", + "laravel/lumen-framework": "^9.0", + "web3-php/web3": "dev-master" + }, + "autoload-dev": { + "psr-4": {} + }, + "scripts": {}, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/php-basic-crud/proxy/composer.lock b/php-basic-crud/proxy/composer.lock new file mode 100644 index 00000000..94c87c9c --- /dev/null +++ b/php-basic-crud/proxy/composer.lock @@ -0,0 +1,5676 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "2e99695a14584ed67a51c81f8636996f", + "packages": [ + { + "name": "brick/math", + "version": "0.9.3", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.9.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.9.3" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" + } + ], + "time": "2021-08-15T20:50:18+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "vimeo/psalm": "^4.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:16:43+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", + "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.2" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-01-12T08:27:12+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ee0db30118f661fb166bcffbf5d82032df484697" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ee0db30118f661fb166bcffbf5d82032df484697", + "reference": "ee0db30118f661fb166bcffbf5d82032df484697", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/3.1.2" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2021-10-11T09:18:27+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "0690bde05318336c7221785f2a932467f98b64ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca", + "reference": "0690bde05318336c7221785f2a932467f98b64ca", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "phpoption/phpoption": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2021-11-21T21:41:47+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.4.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.8.3 || ^2.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.4-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.4.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2021-12-06T18:43:05+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:56:57+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72", + "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.1.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2021-10-06T17:43:30+00:00" + }, + { + "name": "illuminate/auth", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/auth.git", + "reference": "16d997e3a641c7e52e34fb02f61f4ac207e327aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/auth/zipball/16d997e3a641c7e52e34fb02f61f4ac207e327aa", + "reference": "16d997e3a641c7e52e34fb02f61f4ac207e327aa", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/http": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/queue": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "suggest": { + "illuminate/console": "Required to use the auth:clear-resets command (^9.0).", + "illuminate/queue": "Required to fire login / logout events (^9.0).", + "illuminate/session": "Required to use the session based guard (^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Auth\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Auth package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-14T17:21:36+00:00" + }, + { + "name": "illuminate/broadcasting", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/broadcasting.git", + "reference": "32f1661ff4a9fb776e1cad103940b09518ef0a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/broadcasting/zipball/32f1661ff4a9fb776e1cad103940b09518ef0a31", + "reference": "32f1661ff4a9fb776e1cad103940b09518ef0a31", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/bus": "^9.0", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/queue": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "psr/log": "^1.0|^2.0|^3.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Broadcasting\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Broadcasting package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/bus", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/bus.git", + "reference": "b8eeab8d43bc4085e882bfc8583cab6ced4c29e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/bus/zipball/b8eeab8d43bc4085e882bfc8583cab6ced4c29e8", + "reference": "b8eeab8d43bc4085e882bfc8583cab6ced4c29e8", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/pipeline": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "suggest": { + "illuminate/queue": "Required to use closures when chaining jobs (^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Bus\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Bus package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-12T17:47:05+00:00" + }, + { + "name": "illuminate/cache", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/cache.git", + "reference": "52ead4fcaf61d900a17990b06af5656755ca30e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/cache/zipball/52ead4fcaf61d900a17990b06af5656755ca30e2", + "reference": "52ead4fcaf61d900a17990b06af5656755ca30e2", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "provide": { + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "suggest": { + "ext-memcached": "Required to use the memcache cache driver.", + "illuminate/database": "Required to use the database cache driver (^9.0).", + "illuminate/filesystem": "Required to use the file cache driver (^9.0).", + "illuminate/redis": "Required to use the redis cache driver (^9.0).", + "symfony/cache": "Required to use PSR-6 cache bridge (^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Cache package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-14T17:27:32+00:00" + }, + { + "name": "illuminate/collections", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/collections.git", + "reference": "707ab36191228b1a4cf322985796ff7aab5578c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/collections/zipball/707ab36191228b1a4cf322985796ff7aab5578c1", + "reference": "707ab36191228b1a4cf322985796ff7aab5578c1", + "shasum": "" + }, + "require": { + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "php": "^8.0.2" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-09T21:49:11+00:00" + }, + { + "name": "illuminate/conditionable", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "4f7e3d67ceda9a6188757501748982ea9ed5f69a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/4f7e3d67ceda9a6188757501748982ea9ed5f69a", + "reference": "4f7e3d67ceda9a6188757501748982ea9ed5f69a", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-09T14:26:32+00:00" + }, + { + "name": "illuminate/config", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/config.git", + "reference": "d2dc74fdcc89239e1910a8d08b2b2e5ad26a043c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/config/zipball/d2dc74fdcc89239e1910a8d08b2b2e5ad26a043c", + "reference": "d2dc74fdcc89239e1910a8d08b2b2e5ad26a043c", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Config package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T16:16:50+00:00" + }, + { + "name": "illuminate/console", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/console.git", + "reference": "cb3486758b07ae824bc763592d414973a17658b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/console/zipball/cb3486758b07ae824bc763592d414973a17658b7", + "reference": "cb3486758b07ae824bc763592d414973a17658b7", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "symfony/console": "^6.0", + "symfony/process": "^6.0" + }, + "suggest": { + "dragonmantank/cron-expression": "Required to use scheduler (^3.1).", + "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.2).", + "illuminate/bus": "Required to use the scheduled job dispatcher (^9.0).", + "illuminate/container": "Required to use the scheduler (^9.0).", + "illuminate/filesystem": "Required to use the generator command (^9.0).", + "illuminate/queue": "Required to use closures for scheduled jobs (^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Console package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/container", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/container.git", + "reference": "b249d566e8f93b9255d84f4c06a8cc7db24c900c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/container/zipball/b249d566e8f93b9255d84f4c06a8cc7db24c900c", + "reference": "b249d566e8f93b9255d84f4c06a8cc7db24c900c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.0", + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1" + }, + "provide": { + "psr/container-implementation": "1.1|2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Container\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Container package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-05T18:02:43+00:00" + }, + { + "name": "illuminate/contracts", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/contracts.git", + "reference": "c2e3cf2eda10fd3332af0b4a43481cc0af98c437" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/c2e3cf2eda10fd3332af0b4a43481cc0af98c437", + "reference": "c2e3cf2eda10fd3332af0b4a43481cc0af98c437", + "shasum": "" + }, + "require": { + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Contracts package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-11T14:24:50+00:00" + }, + { + "name": "illuminate/database", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/database.git", + "reference": "9a65ca2100cada21ab2e65032821e5d3264da008" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/database/zipball/9a65ca2100cada21ab2e65032821e5d3264da008", + "reference": "9a65ca2100cada21ab2e65032821e5d3264da008", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "symfony/console": "^6.0" + }, + "suggest": { + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "illuminate/console": "Required to use the database commands (^9.0).", + "illuminate/events": "Required to use the observers with Eloquent (^9.0).", + "illuminate/filesystem": "Required to use the migrations (^9.0).", + "illuminate/pagination": "Required to paginate the result set (^9.0).", + "symfony/finder": "Required to use Eloquent model factories (^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Database\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Database package.", + "homepage": "https://laravel.com", + "keywords": [ + "database", + "laravel", + "orm", + "sql" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-12T23:43:59+00:00" + }, + { + "name": "illuminate/encryption", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/encryption.git", + "reference": "61a817a2a7fe3a771db196939f5a627a751049ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/encryption/zipball/61a817a2a7fe3a771db196939f5a627a751049ad", + "reference": "61a817a2a7fe3a771db196939f5a627a751049ad", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Encryption\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Encryption package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/events", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/events.git", + "reference": "b58e0e9b5afc3770505a2694c50afb23d973a75e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/events/zipball/b58e0e9b5afc3770505a2694c50afb23d973a75e", + "reference": "b58e0e9b5afc3770505a2694c50afb23d973a75e", + "shasum": "" + }, + "require": { + "illuminate/bus": "^9.0", + "illuminate/collections": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "functions.php" + ], + "psr-4": { + "Illuminate\\Events\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Events package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/filesystem", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/filesystem.git", + "reference": "8fbb541a9d45ca5dcd459bde9fb23082371f48a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/filesystem/zipball/8fbb541a9d45ca5dcd459bde9fb23082371f48a9", + "reference": "8fbb541a9d45ca5dcd459bde9fb23082371f48a9", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "symfony/finder": "^6.0" + }, + "suggest": { + "ext-ftp": "Required to use the Flysystem FTP driver.", + "illuminate/http": "Required for handling uploaded files (^7.0).", + "league/flysystem": "Required to use the Flysystem local driver (^3.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", + "symfony/mime": "Required to enable support for guessing extensions (^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Filesystem package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-10T16:13:07+00:00" + }, + { + "name": "illuminate/hashing", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/hashing.git", + "reference": "9c67e4a7af74c1d93b7102accd5491969ad2bd86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/hashing/zipball/9c67e4a7af74c1d93b7102accd5491969ad2bd86", + "reference": "9c67e4a7af74c1d93b7102accd5491969ad2bd86", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Hashing\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Hashing package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/http", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/http.git", + "reference": "e0248518e2292eb46a4f019396569f760a07ab5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/http/zipball/e0248518e2292eb46a4f019396569f760a07ab5e", + "reference": "e0248518e2292eb46a4f019396569f760a07ab5e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/session": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "symfony/http-foundation": "^6.0", + "symfony/http-kernel": "^6.0", + "symfony/mime": "^6.0" + }, + "suggest": { + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "guzzlehttp/guzzle": "Required to use the HTTP Client (^7.2)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Http\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Http package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-12T23:43:59+00:00" + }, + { + "name": "illuminate/log", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/log.git", + "reference": "fd12e6928cfdf5303124cbe167a8ce16308502cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/log/zipball/fd12e6928cfdf5303124cbe167a8ce16308502cb", + "reference": "fd12e6928cfdf5303124cbe167a8ce16308502cb", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "monolog/monolog": "^2.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Log package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-03T09:06:04+00:00" + }, + { + "name": "illuminate/macroable", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/macroable.git", + "reference": "25a2c6dac2b7541ecbadef952702e84ae15f5354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/25a2c6dac2b7541ecbadef952702e84ae15f5354", + "reference": "25a2c6dac2b7541ecbadef952702e84ae15f5354", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/pagination", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/pagination.git", + "reference": "c4b992cebde5d0cb5091613f2df7ecf850d96dec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/c4b992cebde5d0cb5091613f2df7ecf850d96dec", + "reference": "c4b992cebde5d0cb5091613f2df7ecf850d96dec", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Pagination\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Pagination package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-15T14:56:31+00:00" + }, + { + "name": "illuminate/pipeline", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/pipeline.git", + "reference": "723820323d87a2c22f017ce7ea124d08e4b65f29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/pipeline/zipball/723820323d87a2c22f017ce7ea124d08e4b65f29", + "reference": "723820323d87a2c22f017ce7ea124d08e4b65f29", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Pipeline\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Pipeline package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/queue", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/queue.git", + "reference": "fd3f4ed84547fb41cb0a3cd8e59125e935d6f73a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/queue/zipball/fd3f4ed84547fb41cb0a3cd8e59125e935d6f73a", + "reference": "fd3f4ed84547fb41cb0a3cd8e59125e935d6f73a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/console": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/database": "^9.0", + "illuminate/filesystem": "^9.0", + "illuminate/pipeline": "^9.0", + "illuminate/support": "^9.0", + "laravel/serializable-closure": "^1.0", + "php": "^8.0.2", + "ramsey/uuid": "^4.2.2", + "symfony/process": "^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.198.1).", + "ext-pcntl": "Required to use all features of the queue worker.", + "ext-posix": "Required to use all features of the queue worker.", + "illuminate/redis": "Required to use the Redis queue driver (^9.0).", + "pda/pheanstalk": "Required to use the Beanstalk queue driver (^4.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Queue\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Queue package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-03T15:18:48+00:00" + }, + { + "name": "illuminate/session", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/session.git", + "reference": "bbda6e9c6fbb61c522fcd5e0a196735b0c628ae5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/session/zipball/bbda6e9c6fbb61c522fcd5e0a196735b0c628ae5", + "reference": "bbda6e9c6fbb61c522fcd5e0a196735b0c628ae5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/filesystem": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "symfony/finder": "^6.0", + "symfony/http-foundation": "^6.0" + }, + "suggest": { + "illuminate/console": "Required to use the session:table command (^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Session\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Session package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/support", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/support.git", + "reference": "cb117bc9a3358d60ade85e5a13d6b82f40ee6049" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/support/zipball/cb117bc9a3358d60ade85e5a13d6b82f40ee6049", + "reference": "cb117bc9a3358d60ade85e5a13d6b82f40ee6049", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^2.0", + "ext-json": "*", + "ext-mbstring": "*", + "illuminate/collections": "^9.0", + "illuminate/conditionable": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "nesbot/carbon": "^2.53.1", + "php": "^8.0.2", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "suggest": { + "illuminate/filesystem": "Required to use the composer class (^9.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", + "symfony/process": "Required to use the composer class (^6.0).", + "symfony/var-dumper": "Required to use the dd function (^6.0).", + "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Support package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-14T17:31:22+00:00" + }, + { + "name": "illuminate/testing", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/testing.git", + "reference": "8147fdeaecc4f0585232c4f926da78b1b4cc7f17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/testing/zipball/8147fdeaecc4f0585232c4f926da78b1b4cc7f17", + "reference": "8147fdeaecc4f0585232c4f926da78b1b4cc7f17", + "shasum": "" + }, + "require": { + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "suggest": { + "brianium/paratest": "Required to run tests in parallel (^6.0).", + "illuminate/console": "Required to assert console commands (^9.0).", + "illuminate/database": "Required to assert databases (^9.0).", + "illuminate/http": "Required to assert responses (^9.0).", + "mockery/mockery": "Required to use mocking (^1.4.4).", + "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Testing\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Testing package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-11T14:51:01+00:00" + }, + { + "name": "illuminate/translation", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/translation.git", + "reference": "8bdac1ceea6be67e8f1c93ad68ac4abe1f91df3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/translation/zipball/8bdac1ceea6be67e8f1c93ad68ac4abe1f91df3f", + "reference": "8bdac1ceea6be67e8f1c93ad68ac4abe1f91df3f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/filesystem": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Translation package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-01T14:44:21+00:00" + }, + { + "name": "illuminate/validation", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/validation.git", + "reference": "805f5fd17a75ce24d7e39a833000ea698d55a695" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/validation/zipball/805f5fd17a75ce24d7e39a833000ea698d55a695", + "reference": "805f5fd17a75ce24d7e39a833000ea698d55a695", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^3.1", + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "illuminate/translation": "^9.0", + "php": "^8.0.2", + "symfony/http-foundation": "^6.0", + "symfony/mime": "^6.0" + }, + "suggest": { + "ext-bcmath": "Required to use the multiple_of validation rule.", + "illuminate/database": "Required to use the database presence verifier (^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Validation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Validation package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-11T14:35:03+00:00" + }, + { + "name": "illuminate/view", + "version": "v9.1.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/view.git", + "reference": "b580a1bcfa76900a59108f86e5cd3ac6c9a3d722" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/view/zipball/b580a1bcfa76900a59108f86e5cd3ac6c9a3d722", + "reference": "b580a1bcfa76900a59108f86e5cd3ac6c9a3d722", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/events": "^9.0", + "illuminate/filesystem": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\View\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate View package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-02-10T15:02:11+00:00" + }, + { + "name": "laravel/lumen-framework", + "version": "v9.0.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/lumen-framework.git", + "reference": "e16c58000ec3651a616bb0f09fd0949f4c8c19ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/lumen-framework/zipball/e16c58000ec3651a616bb0f09fd0949f4c8c19ec", + "reference": "e16c58000ec3651a616bb0f09fd0949f4c8c19ec", + "shasum": "" + }, + "require": { + "dragonmantank/cron-expression": "^3.1", + "illuminate/auth": "^9.0", + "illuminate/broadcasting": "^9.0", + "illuminate/bus": "^9.0", + "illuminate/cache": "^9.0", + "illuminate/collections": "^9.0", + "illuminate/config": "^9.0", + "illuminate/console": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/database": "^9.0", + "illuminate/encryption": "^9.0", + "illuminate/events": "^9.0", + "illuminate/filesystem": "^9.0", + "illuminate/hashing": "^9.0", + "illuminate/http": "^9.0", + "illuminate/log": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/pagination": "^9.0", + "illuminate/pipeline": "^9.0", + "illuminate/queue": "^9.0", + "illuminate/support": "^9.0", + "illuminate/testing": "^9.0", + "illuminate/translation": "^9.0", + "illuminate/validation": "^9.0", + "illuminate/view": "^9.0", + "nikic/fast-route": "^1.3", + "php": "^8.0.2", + "symfony/console": "^6.0", + "symfony/error-handler": "^6.0", + "symfony/http-foundation": "^6.0", + "symfony/http-kernel": "^6.0", + "symfony/mime": "^6.0", + "symfony/var-dumper": "^6.0", + "vlucas/phpdotenv": "^5.4.1" + }, + "require-dev": { + "mockery/mockery": "^1.4.4", + "phpunit/phpunit": "^9.5.8" + }, + "suggest": { + "laravel/tinker": "Required to use the tinker console command (^2.7).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Lumen\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Lumen Framework.", + "homepage": "https://lumen.laravel.com", + "keywords": [ + "framework", + "laravel", + "lumen" + ], + "support": { + "issues": "https://github.com/laravel/lumen-framework/issues", + "source": "https://github.com/laravel/lumen-framework" + }, + "time": "2022-02-15T15:56:07+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/9e4b005daa20b0c161f3845040046dc9ddc1d74e", + "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-02-11T19:23:53+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.3.5", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9", + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7", + "graylog2/gelf-php": "^1.4.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.3", + "phpspec/prophecy": "^1.6.1", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5", + "predis/predis": "^1.1", + "rollbar/rollbar": "^1.3", + "ruflin/elastica": ">=0.90@dev", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.3.5" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2021-10-01T21:08:31+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.56.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "626ec8cbb724cd3c3400c3ed8f730545b744e3f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/626ec8cbb724cd3c3400c3ed8f730545b744e3f4", + "reference": "626ec8cbb724cd3c3400c3ed8f730545b744e3f4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.0", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.54 || ^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.14", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2022-01-21T17:08:38+00:00" + }, + { + "name": "nikic/fast-route", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|~5.7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "FastRoute\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "support": { + "issues": "https://github.com/nikic/FastRoute/issues", + "source": "https://github.com/nikic/FastRoute/tree/master" + }, + "time": "2018-02-13T20:26:39+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "9229e15f2e6ba772f0c55dd6986c563b937170a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/9229e15f2e6ba772f0c55dd6986c563b937170a8", + "reference": "9229e15f2e6ba772f0c55dd6986c563b937170a8", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-01-17T05:32:27+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2021-12-04T23:24:31+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.13", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "1443ab79364eea48665fa8c09ac67f37d1025f7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/1443ab79364eea48665fa8c09ac67f37d1025f7e", + "reference": "1443ab79364eea48665fa8c09ac67f37d1025f7e", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^5.7|^6.0|^9.4", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.13" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2022-01-30T08:50:05+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" + }, + "require-dev": { + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.2.2" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-10-10T03:01:02+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "shasum": "" + }, + "require": { + "brick/math": "^0.8 || ^0.9", + "ext-json": "*", + "php": "^7.2 || ^8.0", + "ramsey/collection": "^1.0", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-php80": "^1.14" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "moontoast/math": "^1.1", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5 || ^9", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + }, + "captainhook": { + "force-install": true + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.2.3" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2021-09-25T23:10:38+00:00" + }, + { + "name": "symfony/console", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "22e8efd019c3270c4f79376234a3f8752cd25490" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/22e8efd019c3270c4f79376234a3f8752cd25490", + "reference": "22e8efd019c3270c4f79376234a3f8752cd25490", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-26T17:23:29+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-01T23:48:49+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "20343b3bad7ebafa38138ddcb97290a24722b57b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/20343b3bad7ebafa38138ddcb97290a24722b57b", + "reference": "20343b3bad7ebafa38138ddcb97290a24722b57b", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934", + "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "aa5422287b75594b90ee9cd807caf8f0df491385" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385", + "reference": "aa5422287b75594b90ee9cd807caf8f0df491385", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-07-15T12:33:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430", + "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-26T17:23:29+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "ad157299ced81a637fade1efcadd688d6deba5c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ad157299ced81a637fade1efcadd688d6deba5c1", + "reference": "ad157299ced81a637fade1efcadd688d6deba5c1", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "9dce179ce52b0f4f669c07fd5e465e5d809a5d3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9dce179ce52b0f4f669c07fd5e465e5d809a5d3b", + "reference": "9dce179ce52b0f4f669c07fd5e465e5d809a5d3b", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<5.4", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/dom-crawler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.0.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-29T18:12:46+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "2cd9601efd040e56f43360daa68f3c6b0534923a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/2cd9601efd040e56f43360daa68f3c6b0534923a", + "reference": "2cd9601efd040e56f43360daa68f3c6b0534923a", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T21:10:46+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "749045c69efb97c70d25d7463abba812e91f3a44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44", + "reference": "749045c69efb97c70d25d7463abba812e91f3a44", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-14T14:02:44+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-30T18:21:41+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-05-27T09:17:38+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:33+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:11+00:00" + }, + { + "name": "symfony/process", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "298ed357274c1868c20a0061df256a1250a6c4af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/298ed357274c1868c20a0061df256a1250a6c4af", + "reference": "298ed357274c1868c20a0061df256a1250a6c4af", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-26T17:23:29+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-04T17:53:12+00:00" + }, + { + "name": "symfony/string", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "71bb15335798f8c4da110911bcf2d2fead7a430d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/71bb15335798f8c4da110911bcf2d2fead7a430d", + "reference": "71bb15335798f8c4da110911bcf2d2fead7a430d", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.3|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-07T00:29:03+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", + "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-07T12:43:40+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "7b701676fc64f9ef11f9b4870f16b48f66be4834" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7b701676fc64f9ef11f9b4870f16b48f66be4834", + "reference": "7b701676fc64f9ef11f9b4870f16b48f66be4834", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-17T16:30:44+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-12-12T23:22:04+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/9bd89e83cecdf8c37b64909454249eaed98b2c89", + "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-01-24T18:59:03+00:00" + }, + { + "name": "web3-php/web3", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/web3-php/web3.git", + "reference": "33950e298ef06f212f7366fc03a362f03b2c0c62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web3-php/web3/zipball/33950e298ef06f212f7366fc03a362f03b2c0c62", + "reference": "33950e298ef06f212f7366fc03a362f03b2c0c62", + "shasum": "" + }, + "require": { + "ext-bcmath": "*", + "guzzlehttp/guzzle": "^7.4.1", + "php": "^8.0", + "phpseclib/phpseclib": "^3.0.13" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.6.0", + "mockery/mockery": "^1.5.0", + "pestphp/pest": "^2.0.0", + "phpstan/phpstan": "^1.4.6", + "symfony/var-dumper": "^5.4.3" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Web3\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Web3 PHP is a supercharged PHP API client that allows you to interact with a generic Ethereum RPC.", + "keywords": [ + "api", + "client", + "ethereum", + "json-rpc", + "php", + "web3" + ], + "support": { + "issues": "https://github.com/web3-php/web3/issues", + "source": "https://github.com/web3-php/web3/tree/master" + }, + "funding": [ + { + "url": "https://paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2022-02-11T21:38:04+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "web3-php/web3": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.0" + }, + "platform-dev": [], + "plugin-api-version": "2.2.0" +} diff --git a/php-basic-crud/proxy/public/index.php b/php-basic-crud/proxy/public/index.php new file mode 100644 index 00000000..9bb65fe2 --- /dev/null +++ b/php-basic-crud/proxy/public/index.php @@ -0,0 +1,67 @@ +configure('app'); + +$web3 = new Web3('http://hardhat:8545'); + +$closure = function (Request $request) use ($web3): JsonResponse { + $hexJsonData = bin2hex( + json_encode([ + 'path' => '/' . ltrim($request->getRequestUri(), '/'), + 'method' => strtoupper($request->getMethod()), + 'payload' => $request->all(), + ], JSON_THROW_ON_ERROR) + ); + + $command = 'docker exec php-basic-crud-hardhat npx hardhat --network localhost php-basic-crud:addInput --input "0x' . $hexJsonData . '"'; + + $commandOutput = explode(' ', Str::after(shell_exec($command), 'to epoch ')); + + $data = [ + 'epoch' => (int)$commandOutput[0], + 'timestamp' => Str::before($commandOutput[2], ','), + 'signer' => Str::before($commandOutput[4], ','), + 'tx' => Str::before($commandOutput[6], ')'), + ]; + + return response()->json([ + 'command_result' => $data, + 'transaction' => $web3->eth()->getTransactionByHash($data['tx']), + 'transaction_receipt' => $web3->eth()->getTransactionReceipt($data['tx']), + ]); +}; + +$pattern = '/{any:.*}'; + +$app->router->get($pattern, $closure); +$app->router->post($pattern, $closure); +$app->router->put($pattern, $closure); +$app->router->patch($pattern, $closure); +$app->router->delete($pattern, $closure); + +$app->run(); diff --git a/php-basic-crud/server/.gitignore b/php-basic-crud/server/.gitignore new file mode 100644 index 00000000..b2cbcbea --- /dev/null +++ b/php-basic-crud/server/.gitignore @@ -0,0 +1,8 @@ +/.idea +__pycache__ +.env +*.ext2 +*.yaml +machine +**/.DS_Store +*.db diff --git a/php-basic-crud/server/Makefile b/php-basic-crud/server/Makefile new file mode 100644 index 00000000..5d806cf8 --- /dev/null +++ b/php-basic-crud/server/Makefile @@ -0,0 +1,73 @@ +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +DAPP_SERVER_MANAGER_TAG := 0.1.0 +DAPP_SERVER_MANAGER_IMG := cartesi/server-manager:$(DAPP_SERVER_MANAGER_TAG) + +CONTAINER_NAME := cartesi-php-basic-crud-dapp +CONTAINER_BASE := /opt/cartesi/php-basic-crud +CONTAINER_DAPP_FS_BIN := /opt/cartesi/php-basic-crud-dapp-fs/php-basic-crud-dapp.ext2 +CONTAINER_MACHINE_DIR := /opt/cartesi/php-basic-crud-machine + +DAPP_FS_BIN := php-basic-crud-dapp.ext2 +BINARIES := rootfs.ext2 linux-5.5.19-ctsi-3.bin rom.bin +MACHINE_DIR := machine + +.PHONY: console clean + +$(MACHINE_DIR): $(DAPP_FS_BIN) $(BINARIES) + @echo "Building cartesi-machine php-basic-crud-dapp instance..." + @if docker inspect $(CONTAINER_NAME) > /dev/null 2>&1; then \ + docker rm -f $(CONTAINER_NAME) > /dev/null; \ + fi + @docker run \ + --name $(CONTAINER_NAME) \ + --hostname server-manager-env \ + --platform linux/amd64 \ + -v `pwd`:$(CONTAINER_BASE) \ + -w $(CONTAINER_BASE) \ + $(DAPP_SERVER_MANAGER_IMG) $(CONTAINER_BASE)/build-machine.sh + @docker cp $(CONTAINER_NAME):$(CONTAINER_MACHINE_DIR) $@ + @docker rm -f $(CONTAINER_NAME) > /dev/null + @echo "$(MACHINE_DIR): OK" + +console: $(DAPP_FS_BIN) $(BINARIES) + @echo "Running cartesi-machine console..." + @docker run --hostname server-manager-env -it --rm \ + -v `pwd`:$(CONTAINER_BASE) \ + -w $(CONTAINER_BASE) \ + --platform linux/amd64 \ + $(DAPP_SERVER_MANAGER_IMG) $(CONTAINER_BASE)/run-machine-console.sh + +$(BINARIES) &: + @echo "Downloading cartesi-machine rom, kernel and rootfs..." + @wget -q -nc -i dependencies -P . + @shasum -c shasumfile + +$(DAPP_FS_BIN): run.sh + @echo "Building php-basic-crud-dapp filesystem..." + @if docker inspect $(CONTAINER_NAME) > /dev/null 2>&1; then \ + docker rm -f $(CONTAINER_NAME) > /dev/null; \ + fi + @docker run \ + --name $(CONTAINER_NAME) \ + --hostname server-manager-env \ + -v `pwd`:$(CONTAINER_BASE) \ + -w $(CONTAINER_BASE) \ + --platform linux/amd64 \ + $(DAPP_SERVER_MANAGER_IMG) $(CONTAINER_BASE)/build-dapp-fs.sh + @docker cp $(CONTAINER_NAME):$(CONTAINER_DAPP_FS_BIN) $@ + @docker rm -f $(CONTAINER_NAME) > /dev/null + @echo "$(DAPP_FS_BIN): OK" + +clean: + @rm -rf $(DAPP_FS_BIN) $(BINARIES) $(MACHINE_DIR) diff --git a/php-basic-crud/server/build-dapp-fs.sh b/php-basic-crud/server/build-dapp-fs.sh new file mode 100755 index 00000000..8b0b3531 --- /dev/null +++ b/php-basic-crud/server/build-dapp-fs.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +DAPP_FS=/opt/cartesi/php-basic-crud-dapp-fs/php-basic-crud-dapp +DAPP_FS_BIN=/opt/cartesi/php-basic-crud-dapp-fs/php-basic-crud-dapp.ext2 + +mkdir -p $DAPP_FS +cp -R ./php $DAPP_FS +cp ./run.sh $DAPP_FS +genext2fs -f -i 512 -b 1024 -d $DAPP_FS $DAPP_FS_BIN +truncate -s %4096 $DAPP_FS_BIN diff --git a/php-basic-crud/server/build-machine.sh b/php-basic-crud/server/build-machine.sh new file mode 100755 index 00000000..5658a050 --- /dev/null +++ b/php-basic-crud/server/build-machine.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +MACHINE_DIR=/opt/cartesi/php-basic-crud-machine + +cartesi-machine \ + --ram-length=128Mi \ + --rollup \ + --flash-drive=label:php-basic-crud-dapp,filename:php-basic-crud-dapp.ext2 \ + --flash-drive=label:root,filename:rootfs.ext2 \ + --ram-image=linux-5.5.19-ctsi-3.bin \ + --rom-image=rom.bin \ + --store=$MACHINE_DIR \ + -- "/mnt/php-basic-crud-dapp/run.sh" diff --git a/php-basic-crud/server/dependencies b/php-basic-crud/server/dependencies new file mode 100644 index 00000000..7f6b4b7a --- /dev/null +++ b/php-basic-crud/server/dependencies @@ -0,0 +1,3 @@ +https://github.com/cartesi/image-kernel/releases/download/v0.9.0/linux-5.5.19-ctsi-3.bin +https://wchfs-media.fra1.digitaloceanspaces.com/cartesi/fs/example-php/rootfs.ext2 +https://github.com/cartesi/machine-emulator-rom/releases/download/v0.8.0/rom.bin diff --git a/php-basic-crud/server/php/App.php b/php-basic-crud/server/php/App.php new file mode 100644 index 00000000..354419dc --- /dev/null +++ b/php-basic-crud/server/php/App.php @@ -0,0 +1,96 @@ +setupDb(); + $this->cURL = new cURL(); + } + + public function handleAdvance(?array $data): void + { + [ + 'path' => $path, + 'method' => $method, + 'payload' => $payload, + ] = $data; + + $result = (new Service($path, $method, $payload))->handle($this->db); + + if (! empty($result)) { + $this->sendNotice($result); + } + } + + public function handleInspect(array $query): void + { + return; // TODO + } + + private function sendNotice(array $result): void + { + $this->cURL->jsonPost('http://127.0.0.1:5004/notice', [ + 'payload' => '0x' . bin2hex(json_encode($result, JSON_THROW_ON_ERROR)), + ]); + } + + private function setupDb() + { + $this->db = new Medoo([ + 'type' => 'sqlite', + 'database' => '../database.db', + 'error' => PDO::ERRMODE_EXCEPTION, + ]); + + $this->db->create('users', [ + 'id' => [ + 'INTEGER', + 'NOT NULL', + 'PRIMARY KEY', + 'AUTOINCREMENT', + ], + 'name' => [ + 'VARCHAR(255)', + 'NOT NULL' + ], + 'email' => [ + 'VARCHAR(255)', + 'NOT NULL' + ], + ]); + + $this->db->create('tasks', [ + 'id' => [ + 'INTEGER', + 'NOT NULL', + 'PRIMARY KEY', + 'AUTOINCREMENT', + ], + 'title' => [ + 'VARCHAR(255)', + 'NOT NULL' + ], + 'description' => [ + 'TEXT', + ], + ]); + } + + public function __destruct() + { + $this->cURL->jsonPost('http://127.0.0.1:5004/finish', [ + 'status' => 'accept', + ]); + } +} diff --git a/php-basic-crud/server/php/Medoo.php b/php-basic-crud/server/php/Medoo.php new file mode 100644 index 00000000..9509053a --- /dev/null +++ b/php-basic-crud/server/php/Medoo.php @@ -0,0 +1,2233 @@ + 'mysql', + * 'database' => 'name', + * 'host' => 'localhost', + * 'username' => 'your_username', + * 'password' => 'your_password', + * + * // [optional] + * 'charset' => 'utf8mb4', + * 'port' => 3306, + * 'prefix' => 'PREFIX_' + * ]); + * ``` + * + * @param array $options Connection options + * @return Medoo + * @throws PDOException + * @link https://medoo.in/api/new + * @codeCoverageIgnore + */ + + public function __construct(array $options) + { + if (isset($options['prefix'])) { + $this->prefix = $options['prefix']; + } + + if (isset($options['testMode']) && $options['testMode'] == true) { + $this->testMode = true; + return; + } + + $options['type'] = $options['type'] ?? $options['database_type']; + + if (!isset($options['pdo'])) { + $options['database'] = $options['database'] ?? $options['database_name']; + + if (!isset($options['socket'])) { + $options['host'] = $options['host'] ?? $options['server'] ?? false; + } + } + + if (isset($options['type'])) { + $this->type = strtolower($options['type']); + + if ($this->type === 'mariadb') { + $this->type = 'mysql'; + } + } + + if (isset($options['logging']) && is_bool($options['logging'])) { + $this->logging = $options['logging']; + } + + $option = $options['option'] ?? []; + $commands = (isset($options['command']) && is_array($options['command'])) ? + $options['command'] : + []; + + switch ($this->type) { + + case 'mysql': + // Make MySQL using standard quoted identifier. + $commands[] = 'SET SQL_MODE=ANSI_QUOTES'; + + break; + + case 'mssql': + // Keep MSSQL QUOTED_IDENTIFIER is ON for standard quoting. + $commands[] = 'SET QUOTED_IDENTIFIER ON'; + + // Make ANSI_NULLS is ON for NULL value. + $commands[] = 'SET ANSI_NULLS ON'; + + break; + } + + if (isset($options['pdo'])) { + if (!$options['pdo'] instanceof PDO) { + throw new InvalidArgumentException('Invalid PDO object supplied.'); + } + + $this->pdo = $options['pdo']; + + foreach ($commands as $value) { + $this->pdo->exec($value); + } + + return; + } + + if (isset($options['dsn'])) { + if (is_array($options['dsn']) && isset($options['dsn']['driver'])) { + $attr = $options['dsn']; + } else { + throw new InvalidArgumentException('Invalid DSN option supplied.'); + } + } else { + if ( + isset($options['port']) && + is_int($options['port'] * 1) + ) { + $port = $options['port']; + } + + $isPort = isset($port); + + switch ($this->type) { + + case 'mysql': + $attr = [ + 'driver' => 'mysql', + 'dbname' => $options['database'] + ]; + + if (isset($options['socket'])) { + $attr['unix_socket'] = $options['socket']; + } else { + $attr['host'] = $options['host']; + + if ($isPort) { + $attr['port'] = $port; + } + } + + break; + + case 'pgsql': + $attr = [ + 'driver' => 'pgsql', + 'host' => $options['host'], + 'dbname' => $options['database'] + ]; + + if ($isPort) { + $attr['port'] = $port; + } + + break; + + case 'sybase': + $attr = [ + 'driver' => 'dblib', + 'host' => $options['host'], + 'dbname' => $options['database'] + ]; + + if ($isPort) { + $attr['port'] = $port; + } + + break; + + case 'oracle': + $attr = [ + 'driver' => 'oci', + 'dbname' => $options['host'] ? + '//' . $options['host'] . ($isPort ? ':' . $port : ':1521') . '/' . $options['database'] : + $options['database'] + ]; + + if (isset($options['charset'])) { + $attr['charset'] = $options['charset']; + } + + break; + + case 'mssql': + if (isset($options['driver']) && $options['driver'] === 'dblib') { + $attr = [ + 'driver' => 'dblib', + 'host' => $options['host'] . ($isPort ? ':' . $port : ''), + 'dbname' => $options['database'] + ]; + + if (isset($options['appname'])) { + $attr['appname'] = $options['appname']; + } + + if (isset($options['charset'])) { + $attr['charset'] = $options['charset']; + } + } else { + $attr = [ + 'driver' => 'sqlsrv', + 'Server' => $options['host'] . ($isPort ? ',' . $port : ''), + 'Database' => $options['database'] + ]; + + if (isset($options['appname'])) { + $attr['APP'] = $options['appname']; + } + + $config = [ + 'ApplicationIntent', + 'AttachDBFileName', + 'Authentication', + 'ColumnEncryption', + 'ConnectionPooling', + 'Encrypt', + 'Failover_Partner', + 'KeyStoreAuthentication', + 'KeyStorePrincipalId', + 'KeyStoreSecret', + 'LoginTimeout', + 'MultipleActiveResultSets', + 'MultiSubnetFailover', + 'Scrollable', + 'TraceFile', + 'TraceOn', + 'TransactionIsolation', + 'TransparentNetworkIPResolution', + 'TrustServerCertificate', + 'WSID', + ]; + + foreach ($config as $value) { + $keyname = strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $value)); + + if (isset($options[$keyname])) { + $attr[$value] = $options[$keyname]; + } + } + } + + break; + + case 'sqlite': + $attr = [ + 'driver' => 'sqlite', + $options['database'] + ]; + + break; + } + } + + if (!isset($attr)) { + throw new InvalidArgumentException('Incorrect connection options.'); + } + + $driver = $attr['driver']; + + if (!in_array($driver, PDO::getAvailableDrivers())) { + throw new InvalidArgumentException("Unsupported PDO driver: {$driver}."); + } + + unset($attr['driver']); + + $stack = []; + + foreach ($attr as $key => $value) { + $stack[] = is_int($key) ? $value : $key . '=' . $value; + } + + $dsn = $driver . ':' . implode(';', $stack); + + if ( + in_array($this->type, ['mysql', 'pgsql', 'sybase', 'mssql']) && + isset($options['charset']) + ) { + $commands[] = "SET NAMES '{$options['charset']}'" . ( + $this->type === 'mysql' && isset($options['collation']) ? + " COLLATE '{$options['collation']}'" : '' + ); + } + + $this->dsn = $dsn; + + try { + $this->pdo = new PDO( + $dsn, + $options['username'] ?? null, + $options['password'] ?? null, + $option + ); + + if (isset($options['error'])) { + $this->pdo->setAttribute( + PDO::ATTR_ERRMODE, + in_array($options['error'], [ + PDO::ERRMODE_SILENT, + PDO::ERRMODE_WARNING, + PDO::ERRMODE_EXCEPTION + ]) ? + $options['error'] : + PDO::ERRMODE_SILENT + ); + } + + foreach ($commands as $value) { + $this->pdo->exec($value); + } + } catch (PDOException $e) { + throw new PDOException($e->getMessage()); + } + } + + /** + * Generate a new map key for placeholder. + * + * @return string + */ + protected function mapKey(): string + { + return ':MeD' . $this->guid++ . '_mK'; + } + + /** + * Execute customized raw statement. + * + * @param string $statement The raw SQL statement. + * @param array $map The array of input parameters value for prepared statement. + * @return \PDOStatement|null + */ + public function query(string $statement, array $map = []): ?PDOStatement + { + $raw = $this->raw($statement, $map); + $statement = $this->buildRaw($raw, $map); + + return $this->exec($statement, $map); + } + + /** + * Execute the raw statement. + * + * @param string $statement The SQL statement. + * @param array $map The array of input parameters value for prepared statement. + * @codeCoverageIgnore + * @return \PDOStatement|null + */ + public function exec(string $statement, array $map = [], callable $callback = null): ?PDOStatement + { + $this->statement = null; + $this->errorInfo = null; + $this->error = null; + + if ($this->testMode) { + $this->queryString = $this->generate($statement, $map); + return null; + } + + if ($this->debugMode) { + if ($this->debugLogging) { + $this->debugLogs[] = $this->generate($statement, $map); + return null; + } + + echo $this->generate($statement, $map); + + $this->debugMode = false; + + return null; + } + + if ($this->logging) { + $this->logs[] = [$statement, $map]; + } else { + $this->logs = [[$statement, $map]]; + } + + $statement = $this->pdo->prepare($statement); + $errorInfo = $this->pdo->errorInfo(); + + if ($errorInfo[0] !== '00000') { + $this->errorInfo = $errorInfo; + $this->error = $errorInfo[2]; + + return null; + } + + foreach ($map as $key => $value) { + $statement->bindValue($key, $value[0], $value[1]); + } + + if (is_callable($callback)) { + $this->pdo->beginTransaction(); + $callback($statement); + $execute = $statement->execute(); + $this->pdo->commit(); + } else { + $execute = $statement->execute(); + } + + $errorInfo = $statement->errorInfo(); + + if ($errorInfo[0] !== '00000') { + $this->errorInfo = $errorInfo; + $this->error = $errorInfo[2]; + + return null; + } + + if ($execute) { + $this->statement = $statement; + } + + return $statement; + } + + /** + * Generate readable statement. + * + * @param string $statement + * @param array $map + * @codeCoverageIgnore + * @return string + */ + protected function generate(string $statement, array $map): string + { + $identifier = [ + 'mysql' => '`$1`', + 'mssql' => '[$1]' + ]; + + $statement = preg_replace( + '/(?!\'[^\s]+\s?)"([\p{L}_][\p{L}\p{N}@$#\-_]*)"(?!\s?[^\s]+\')/u', + $identifier[$this->type] ?? '"$1"', + $statement + ); + + foreach ($map as $key => $value) { + if ($value[1] === PDO::PARAM_STR) { + $replace = $this->quote($value[0]); + } elseif ($value[1] === PDO::PARAM_NULL) { + $replace = 'NULL'; + } elseif ($value[1] === PDO::PARAM_LOB) { + $replace = '{LOB_DATA}'; + } else { + $replace = $value[0] . ''; + } + + $statement = str_replace($key, $replace, $statement); + } + + return $statement; + } + + /** + * Build a raw object. + * + * @param string $string The raw string. + * @param array $map The array of mapping data for the raw string. + * @return Medoo::raw + */ + public static function raw(string $string, array $map = []): Raw + { + $raw = new Raw(); + + $raw->map = $map; + $raw->value = $string; + + return $raw; + } + + /** + * Finds whether the object is raw. + * + * @param object $object + * @return bool + */ + protected function isRaw($object): bool + { + return $object instanceof Raw; + } + + /** + * Generate the actual query from the raw object. + * + * @param mixed $raw + * @param array $map + * @return string|null + */ + protected function buildRaw($raw, array &$map): ?string + { + if (!$this->isRaw($raw)) { + return null; + } + + $query = preg_replace_callback( + '/(([`\']).*?)?((FROM|TABLE|INTO|UPDATE|JOIN)\s*)?\<(([\p{L}_][\p{L}\p{N}@$#\-_]*)(\.[\p{L}_][\p{L}\p{N}@$#\-_]*)?)\>([^,]*?\2)?/u', + function ($matches) { + if (!empty($matches[2]) && isset($matches[8])) { + return $matches[0]; + } + + if (!empty($matches[4])) { + return $matches[1] . $matches[4] . ' ' . $this->tableQuote($matches[5]); + } + + return $matches[1] . $this->columnQuote($matches[5]); + }, + $raw->value + ); + + $rawMap = $raw->map; + + if (!empty($rawMap)) { + foreach ($rawMap as $key => $value) { + $map[$key] = $this->typeMap($value, gettype($value)); + } + } + + return $query; + } + + /** + * Quote a string for use in a query. + * + * @param string $string + * @return string + */ + public function quote(string $string): string + { + if ($this->type === 'mysql') { + return "'" . preg_replace(['/([\'"])/', '/(\\\\\\\")/'], ["\\\\\${1}", '\\\${1}'], $string) . "'"; + } + + return "'" . preg_replace('/\'/', '\'\'', $string) . "'"; + } + + /** + * Quote table name for use in a query. + * + * @param string $table + * @return string + */ + public function tableQuote(string $table): string + { + if (preg_match('/^[\p{L}_][\p{L}\p{N}@$#\-_]*$/u', $table)) { + return '"' . $this->prefix . $table . '"'; + } + + throw new InvalidArgumentException("Incorrect table name: {$table}."); + } + + /** + * Quote column name for use in a query. + * + * @param string $column + * @return string + */ + public function columnQuote(string $column): string + { + if (preg_match('/^[\p{L}_][\p{L}\p{N}@$#\-_]*(\.?[\p{L}_][\p{L}\p{N}@$#\-_]*)?$/u', $column)) { + return strpos($column, '.') !== false ? + '"' . $this->prefix . str_replace('.', '"."', $column) . '"' : + '"' . $column . '"'; + } + + throw new InvalidArgumentException("Incorrect column name: {$column}."); + } + + /** + * Mapping the type name as PDO data type. + * + * @param mixed $value + * @param string $type + * @return array + */ + protected function typeMap($value, string $type): array + { + $map = [ + 'NULL' => PDO::PARAM_NULL, + 'integer' => PDO::PARAM_INT, + 'double' => PDO::PARAM_STR, + 'boolean' => PDO::PARAM_BOOL, + 'string' => PDO::PARAM_STR, + 'object' => PDO::PARAM_STR, + 'resource' => PDO::PARAM_LOB + ]; + + if ($type === 'boolean') { + $value = ($value ? '1' : '0'); + } elseif ($type === 'NULL') { + $value = null; + } + + return [$value, $map[$type]]; + } + + /** + * Build the statement part for the column stack. + * + * @param array|string $columns + * @param array $map + * @param bool $root + * @param bool $isJoin + * @return string + */ + protected function columnPush(&$columns, array &$map, bool $root, bool $isJoin = false): string + { + if ($columns === '*') { + return $columns; + } + + $stack = []; + $hasDistinct = false; + + if (is_string($columns)) { + $columns = [$columns]; + } + + foreach ($columns as $key => $value) { + $isIntKey = is_int($key); + $isArrayValue = is_array($value); + + if (!$isIntKey && $isArrayValue && $root && count(array_keys($columns)) === 1) { + $stack[] = $this->columnQuote($key); + $stack[] = $this->columnPush($value, $map, false, $isJoin); + } elseif ($isArrayValue) { + $stack[] = $this->columnPush($value, $map, false, $isJoin); + } elseif (!$isIntKey && $raw = $this->buildRaw($value, $map)) { + preg_match('/(?[\p{L}_][\p{L}\p{N}@$#\-_\.]*)(\s*\[(?(String|Bool|Int|Number))\])?/u', $key, $match); + $stack[] = "{$raw} AS {$this->columnQuote($match['column'])}"; + } elseif ($isIntKey && is_string($value)) { + if ($isJoin && strpos($value, '*') !== false) { + throw new InvalidArgumentException('Cannot use table.* to select all columns while joining table.'); + } + + preg_match('/(?[\p{L}_][\p{L}\p{N}@$#\-_\.]*)(?:\s*\((?[\p{L}_][\p{L}\p{N}@$#\-_]*)\))?(?:\s*\[(?(?:String|Bool|Int|Number|Object|JSON))\])?/u', $value, $match); + + $columnString = ''; + + if (!empty($match['alias'])) { + $columnString = "{$this->columnQuote($match['column'])} AS {$this->columnQuote($match['alias'])}"; + $columns[$key] = $match['alias']; + + if (!empty($match['type'])) { + $columns[$key] .= ' [' . $match['type'] . ']'; + } + } else { + $columnString = $this->columnQuote($match['column']); + } + + if (!$hasDistinct && strpos($value, '@') === 0) { + $columnString = 'DISTINCT ' . $columnString; + $hasDistinct = true; + array_unshift($stack, $columnString); + + continue; + } + + $stack[] = $columnString; + } + } + + return implode(',', $stack); + } + + /** + * Implode where conditions. + * + * @param array $data + * @param array $map + * @param string $conjunctor + * @return string + */ + protected function dataImplode(array $data, array &$map, string $conjunctor): string + { + $stack = []; + + foreach ($data as $key => $value) { + $type = gettype($value); + + if ( + $type === 'array' && + preg_match("/^(AND|OR)(\s+#.*)?$/", $key, $relationMatch) + ) { + $stack[] = '(' . $this->dataImplode($value, $map, ' ' . $relationMatch[1]) . ')'; + continue; + } + + $mapKey = $this->mapKey(); + $isIndex = is_int($key); + + preg_match( + '/([\p{L}_][\p{L}\p{N}@$#\-_\.]*)(\[(?.*)\])?([\p{L}_][\p{L}\p{N}@$#\-_\.]*)?/u', + $isIndex ? $value : $key, + $match + ); + + $column = $this->columnQuote($match[1]); + $operator = $match['operator'] ?? null; + + if ($isIndex && isset($match[4]) && in_array($operator, ['>', '>=', '<', '<=', '=', '!='])) { + $stack[] = "${column} ${operator} " . $this->columnQuote($match[4]); + continue; + } + + if ($operator && $operator != '=') { + if (in_array($operator, ['>', '>=', '<', '<='])) { + $condition = "{$column} {$operator} "; + + if (is_numeric($value)) { + $condition .= $mapKey; + $map[$mapKey] = [$value, is_float($value) ? PDO::PARAM_STR : PDO::PARAM_INT]; + } elseif ($raw = $this->buildRaw($value, $map)) { + $condition .= $raw; + } else { + $condition .= $mapKey; + $map[$mapKey] = [$value, PDO::PARAM_STR]; + } + + $stack[] = $condition; + } elseif ($operator === '!') { + switch ($type) { + + case 'NULL': + $stack[] = $column . ' IS NOT NULL'; + break; + + case 'array': + $placeholders = []; + + foreach ($value as $index => $item) { + $stackKey = $mapKey . $index . '_i'; + $placeholders[] = $stackKey; + $map[$stackKey] = $this->typeMap($item, gettype($item)); + } + + $stack[] = $column . ' NOT IN (' . implode(', ', $placeholders) . ')'; + break; + + case 'object': + if ($raw = $this->buildRaw($value, $map)) { + $stack[] = "{$column} != {$raw}"; + } + break; + + case 'integer': + case 'double': + case 'boolean': + case 'string': + $stack[] = "{$column} != {$mapKey}"; + $map[$mapKey] = $this->typeMap($value, $type); + break; + } + } elseif ($operator === '~' || $operator === '!~') { + if ($type !== 'array') { + $value = [$value]; + } + + $connector = ' OR '; + $data = array_values($value); + + if (is_array($data[0])) { + if (isset($value['AND']) || isset($value['OR'])) { + $connector = ' ' . array_keys($value)[0] . ' '; + $value = $data[0]; + } + } + + $likeClauses = []; + + foreach ($value as $index => $item) { + $item = strval($item); + + if (!preg_match('/((?' || $operator === '><') { + if ($type === 'array') { + if ($operator === '><') { + $column .= ' NOT'; + } + + if ($this->isRaw($value[0]) && $this->isRaw($value[1])) { + $stack[] = "({$column} BETWEEN {$this->buildRaw($value[0], $map)} AND {$this->buildRaw($value[1], $map)})"; + } else { + $stack[] = "({$column} BETWEEN {$mapKey}a AND {$mapKey}b)"; + $dataType = (is_numeric($value[0]) && is_numeric($value[1])) ? PDO::PARAM_INT : PDO::PARAM_STR; + + $map[$mapKey . 'a'] = [$value[0], $dataType]; + $map[$mapKey . 'b'] = [$value[1], $dataType]; + } + } + } elseif ($operator === 'REGEXP') { + $stack[] = "{$column} REGEXP {$mapKey}"; + $map[$mapKey] = [$value, PDO::PARAM_STR]; + } else { + throw new InvalidArgumentException("Invalid operator [{$operator}] for column {$column} supplied."); + } + + continue; + } + + switch ($type) { + + case 'NULL': + $stack[] = $column . ' IS NULL'; + break; + + case 'array': + $placeholders = []; + + foreach ($value as $index => $item) { + $stackKey = $mapKey . $index . '_i'; + + $placeholders[] = $stackKey; + $map[$stackKey] = $this->typeMap($item, gettype($item)); + } + + $stack[] = $column . ' IN (' . implode(', ', $placeholders) . ')'; + break; + + case 'object': + if ($raw = $this->buildRaw($value, $map)) { + $stack[] = "{$column} = {$raw}"; + } + break; + + case 'integer': + case 'double': + case 'boolean': + case 'string': + $stack[] = "{$column} = {$mapKey}"; + $map[$mapKey] = $this->typeMap($value, $type); + break; + } + } + + return implode($conjunctor . ' ', $stack); + } + + /** + * Build the where clause. + * + * @param array|null $where + * @param array $map + * @return string + */ + protected function whereClause($where, array &$map): string + { + $clause = ''; + + if (is_array($where)) { + $conditions = array_diff_key($where, array_flip( + ['GROUP', 'ORDER', 'HAVING', 'LIMIT', 'LIKE', 'MATCH'] + )); + + if (!empty($conditions)) { + $clause = ' WHERE ' . $this->dataImplode($conditions, $map, ' AND'); + } + + if (isset($where['MATCH']) && $this->type === 'mysql') { + $match = $where['MATCH']; + + if (is_array($match) && isset($match['columns'], $match['keyword'])) { + $mode = ''; + + $options = [ + 'natural' => 'IN NATURAL LANGUAGE MODE', + 'natural+query' => 'IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION', + 'boolean' => 'IN BOOLEAN MODE', + 'query' => 'WITH QUERY EXPANSION' + ]; + + if (isset($match['mode'], $options[$match['mode']])) { + $mode = ' ' . $options[$match['mode']]; + } + + $columns = implode(', ', array_map([$this, 'columnQuote'], $match['columns'])); + $mapKey = $this->mapKey(); + $map[$mapKey] = [$match['keyword'], PDO::PARAM_STR]; + $clause .= ($clause !== '' ? ' AND ' : ' WHERE') . ' MATCH (' . $columns . ') AGAINST (' . $mapKey . $mode . ')'; + } + } + + if (isset($where['GROUP'])) { + $group = $where['GROUP']; + + if (is_array($group)) { + $stack = []; + + foreach ($group as $column => $value) { + $stack[] = $this->columnQuote($value); + } + + $clause .= ' GROUP BY ' . implode(',', $stack); + } elseif ($raw = $this->buildRaw($group, $map)) { + $clause .= ' GROUP BY ' . $raw; + } else { + $clause .= ' GROUP BY ' . $this->columnQuote($group); + } + } + + if (isset($where['HAVING'])) { + $having = $where['HAVING']; + + if ($raw = $this->buildRaw($having, $map)) { + $clause .= ' HAVING ' . $raw; + } else { + $clause .= ' HAVING ' . $this->dataImplode($having, $map, ' AND'); + } + } + + if (isset($where['ORDER'])) { + $order = $where['ORDER']; + + if (is_array($order)) { + $stack = []; + + foreach ($order as $column => $value) { + if (is_array($value)) { + $valueStack = []; + + foreach ($value as $item) { + $valueStack[] = is_int($item) ? $item : $this->quote($item); + } + + $valueString = implode(',', $valueStack); + $stack[] = "FIELD({$this->columnQuote($column)}, {$valueString})"; + } elseif ($value === 'ASC' || $value === 'DESC') { + $stack[] = $this->columnQuote($column) . ' ' . $value; + } elseif (is_int($column)) { + $stack[] = $this->columnQuote($value); + } + } + + $clause .= ' ORDER BY ' . implode(',', $stack); + } elseif ($raw = $this->buildRaw($order, $map)) { + $clause .= ' ORDER BY ' . $raw; + } else { + $clause .= ' ORDER BY ' . $this->columnQuote($order); + } + } + + if (isset($where['LIMIT'])) { + $limit = $where['LIMIT']; + + if (in_array($this->type, ['oracle', 'mssql'])) { + if ($this->type === 'mssql' && !isset($where['ORDER'])) { + $clause .= ' ORDER BY (SELECT 0)'; + } + + if (is_numeric($limit)) { + $limit = [0, $limit]; + } + + if ( + is_array($limit) && + is_numeric($limit[0]) && + is_numeric($limit[1]) + ) { + $clause .= " OFFSET {$limit[0]} ROWS FETCH NEXT {$limit[1]} ROWS ONLY"; + } + } else { + if (is_numeric($limit)) { + $clause .= ' LIMIT ' . $limit; + } elseif ( + is_array($limit) && + is_numeric($limit[0]) && + is_numeric($limit[1]) + ) { + $clause .= " LIMIT {$limit[1]} OFFSET {$limit[0]}"; + } + } + } + } elseif ($raw = $this->buildRaw($where, $map)) { + $clause .= ' ' . $raw; + } + + return $clause; + } + + /** + * Build statement for the select query. + * + * @param string $table + * @param array $map + * @param array|string $join + * @param array|string $columns + * @param array $where + * @param string $columnFn + * @return string + */ + protected function selectContext( + string $table, + array &$map, + $join, + &$columns = null, + $where = null, + $columnFn = null + ): string { + preg_match('/(?[\p{L}_][\p{L}\p{N}@$#\-_]*)\s*\((?[\p{L}_][\p{L}\p{N}@$#\-_]*)\)/u', $table, $tableMatch); + + if (isset($tableMatch['table'], $tableMatch['alias'])) { + $table = $this->tableQuote($tableMatch['table']); + $tableAlias = $this->tableQuote($tableMatch['alias']); + $tableQuery = "{$table} AS {$tableAlias}"; + } else { + $table = $this->tableQuote($table); + $tableQuery = $table; + } + + $isJoin = $this->isJoin($join); + + if ($isJoin) { + $tableQuery .= ' ' . $this->buildJoin($tableAlias ?? $table, $join, $map); + } else { + if (is_null($columns)) { + if ( + !is_null($where) || + (is_array($join) && isset($columnFn)) + ) { + $where = $join; + $columns = null; + } else { + $where = null; + $columns = $join; + } + } else { + $where = $columns; + $columns = $join; + } + } + + if (isset($columnFn)) { + if ($columnFn === 1) { + $column = '1'; + + if (is_null($where)) { + $where = $columns; + } + } elseif ($raw = $this->buildRaw($columnFn, $map)) { + $column = $raw; + } else { + if (empty($columns) || $this->isRaw($columns)) { + $columns = '*'; + $where = $join; + } + + $column = $columnFn . '(' . $this->columnPush($columns, $map, true) . ')'; + } + } else { + $column = $this->columnPush($columns, $map, true, $isJoin); + } + + return 'SELECT ' . $column . ' FROM ' . $tableQuery . $this->whereClause($where, $map); + } + + /** + * Determine the array is with join syntax. + * + * @param mixed $join + * @return bool + */ + protected function isJoin($join): bool + { + if (!is_array($join)) { + return false; + } + + $keys = array_keys($join); + + if ( + isset($keys[0]) && + is_string($keys[0]) && + strpos($keys[0], '[') === 0 + ) { + return true; + } + + return false; + } + + /** + * Build the join statement. + * + * @param string $table + * @param array $join + * @param array $map + * @return string + */ + protected function buildJoin(string $table, array $join, array &$map): string + { + $tableJoin = []; + $type = [ + '>' => 'LEFT', + '<' => 'RIGHT', + '<>' => 'FULL', + '><' => 'INNER' + ]; + + foreach ($join as $subtable => $relation) { + preg_match('/(\[(?\<\>?|\>\[\p{L}_][\p{L}\p{N}@$#\-_]*)\s?(\((?[\p{L}_][\p{L}\p{N}@$#\-_]*)\))?/u', $subtable, $match); + + if ($match['join'] === '' || $match['table'] === '') { + continue; + } + + if (is_string($relation)) { + $relation = 'USING ("' . $relation . '")'; + } elseif (is_array($relation)) { + // For ['column1', 'column2'] + if (isset($relation[0])) { + $relation = 'USING ("' . implode('", "', $relation) . '")'; + } else { + $joins = []; + + foreach ($relation as $key => $value) { + if ($key === 'AND' && is_array($value)) { + $joins[] = $this->dataImplode($value, $map, ' AND'); + continue; + } + + $joins[] = ( + strpos($key, '.') > 0 ? + // For ['tableB.column' => 'column'] + $this->columnQuote($key) : + + // For ['column1' => 'column2'] + $table . '.' . $this->columnQuote($key) + ) . + ' = ' . + $this->tableQuote($match['alias'] ?? $match['table']) . '.' . $this->columnQuote($value); + } + + $relation = 'ON ' . implode(' AND ', $joins); + } + } elseif ($raw = $this->buildRaw($relation, $map)) { + $relation = $raw; + } + + $tableName = $this->tableQuote($match['table']); + + if (isset($match['alias'])) { + $tableName .= ' AS ' . $this->tableQuote($match['alias']); + } + + $tableJoin[] = $type[$match['join']] . " JOIN ${tableName} ${relation}"; + } + + return implode(' ', $tableJoin); + } + + /** + * Mapping columns for the stack. + * + * @param array|string $columns + * @param array $stack + * @param bool $root + * @return array + */ + protected function columnMap($columns, array &$stack, bool $root): array + { + if ($columns === '*') { + return $stack; + } + + foreach ($columns as $key => $value) { + if (is_int($key)) { + preg_match('/([\p{L}_][\p{L}\p{N}@$#\-_]*\.)?(?[\p{L}_][\p{L}\p{N}@$#\-_]*)(?:\s*\((?[\p{L}_][\p{L}\p{N}@$#\-_]*)\))?(?:\s*\[(?(?:String|Bool|Int|Number|Object|JSON))\])?/u', $value, $keyMatch); + + $columnKey = !empty($keyMatch['alias']) ? + $keyMatch['alias'] : + $keyMatch['column']; + + $stack[$value] = isset($keyMatch['type']) ? + [$columnKey, $keyMatch['type']] : + [$columnKey, 'String']; + } elseif ($this->isRaw($value)) { + preg_match('/([\p{L}_][\p{L}\p{N}@$#\-_]*\.)?(?[\p{L}_][\p{L}\p{N}@$#\-_]*)(\s*\[(?(String|Bool|Int|Number))\])?/u', $key, $keyMatch); + $columnKey = $keyMatch['column']; + + $stack[$key] = isset($keyMatch['type']) ? + [$columnKey, $keyMatch['type']] : + [$columnKey, 'String']; + } elseif (!is_int($key) && is_array($value)) { + if ($root && count(array_keys($columns)) === 1) { + $stack[$key] = [$key, 'String']; + } + + $this->columnMap($value, $stack, false); + } + } + + return $stack; + } + + /** + * Mapping the data from the table. + * + * @param array $data + * @param array $columns + * @param array $columnMap + * @param array $stack + * @param bool $root + * @param array $result + * @codeCoverageIgnore + * @return void + */ + protected function dataMap( + array $data, + array $columns, + array $columnMap, + array &$stack, + bool $root, + array &$result = null + ): void { + if ($root) { + $columnsKey = array_keys($columns); + + if (count($columnsKey) === 1 && is_array($columns[$columnsKey[0]])) { + $indexKey = array_keys($columns)[0]; + $dataKey = preg_replace("/^[\p{L}_][\p{L}\p{N}@$#\-_]*\./u", '', $indexKey); + $currentStack = []; + + foreach ($data as $item) { + $this->dataMap($data, $columns[$indexKey], $columnMap, $currentStack, false, $result); + $index = $data[$dataKey]; + + if (isset($result)) { + $result[$index] = $currentStack; + } else { + $stack[$index] = $currentStack; + } + } + } else { + $currentStack = []; + $this->dataMap($data, $columns, $columnMap, $currentStack, false, $result); + + if (isset($result)) { + $result[] = $currentStack; + } else { + $stack = $currentStack; + } + } + + return; + } + + foreach ($columns as $key => $value) { + $isRaw = $this->isRaw($value); + + if (is_int($key) || $isRaw) { + $map = $columnMap[$isRaw ? $key : $value]; + $columnKey = $map[0]; + $item = $data[$columnKey]; + + if (isset($map[1])) { + if ($isRaw && in_array($map[1], ['Object', 'JSON'])) { + continue; + } + + if (is_null($item)) { + $stack[$columnKey] = null; + continue; + } + + switch ($map[1]) { + + case 'Number': + $stack[$columnKey] = (float) $item; + break; + + case 'Int': + $stack[$columnKey] = (int) $item; + break; + + case 'Bool': + $stack[$columnKey] = (bool) $item; + break; + + case 'Object': + $stack[$columnKey] = unserialize($item); + break; + + case 'JSON': + $stack[$columnKey] = json_decode($item, true); + break; + + case 'String': + $stack[$columnKey] = $item; + break; + } + } else { + $stack[$columnKey] = $item; + } + } else { + $currentStack = []; + $this->dataMap($data, $value, $columnMap, $currentStack, false, $result); + + $stack[$key] = $currentStack; + } + } + } + + /** + * Build and execute returning query. + * + * @param string $query + * @param array $map + * @param array $data + * @return \PDOStatement|null + */ + private function returningQuery($query, &$map, &$data): ?PDOStatement + { + $returnColumns = array_map( + function ($value) { + return $value[0]; + }, + $data + ); + + $query .= ' RETURNING ' . + implode(', ', array_map([$this, 'columnQuote'], $returnColumns)) . + ' INTO ' . + implode(', ', array_keys($data)); + + return $this->exec($query, $map, function ($statement) use (&$data) { + // @codeCoverageIgnoreStart + foreach ($data as $key => $return) { + if (isset($return[3])) { + $statement->bindParam($key, $data[$key][1], $return[2], $return[3]); + } else { + $statement->bindParam($key, $data[$key][1], $return[2]); + } + } + // @codeCoverageIgnoreEnd + }); + } + + /** + * Create a table. + * + * @param string $table + * @param array $columns Columns definition. + * @param array $options Additional table options for creating a table. + * @return \PDOStatement|null + */ + public function create(string $table, $columns, $options = null): ?PDOStatement + { + $stack = []; + $tableOption = ''; + $tableName = $this->tableQuote($table); + + foreach ($columns as $name => $definition) { + if (is_int($name)) { + $stack[] = preg_replace('/\<([\p{L}_][\p{L}\p{N}@$#\-_]*)\>/u', '"$1"', $definition); + } elseif (is_array($definition)) { + $stack[] = $this->columnQuote($name) . ' ' . implode(' ', $definition); + } elseif (is_string($definition)) { + $stack[] = $this->columnQuote($name) . ' ' . $definition; + } + } + + if (is_array($options)) { + $optionStack = []; + + foreach ($options as $key => $value) { + if (is_string($value) || is_int($value)) { + $optionStack[] = "{$key} = {$value}"; + } + } + + $tableOption = ' ' . implode(', ', $optionStack); + } elseif (is_string($options)) { + $tableOption = ' ' . $options; + } + + $command = 'CREATE TABLE'; + + if (in_array($this->type, ['mysql', 'pgsql', 'sqlite'])) { + $command .= ' IF NOT EXISTS'; + } + + return $this->exec("{$command} {$tableName} (" . implode(', ', $stack) . "){$tableOption}"); + } + + /** + * Drop a table. + * + * @param string $table + * @return \PDOStatement|null + */ + public function drop(string $table): ?PDOStatement + { + return $this->exec('DROP TABLE IF EXISTS ' . $this->tableQuote($this->prefix . $table)); + } + + /** + * Select data from the table. + * + * @param string $table + * @param array $join + * @param array|string $columns + * @param array $where + * @return array|null + */ + public function select(string $table, $join, $columns = null, $where = null): ?array + { + $map = []; + $result = []; + $columnMap = []; + + $args = func_get_args(); + $lastArgs = $args[array_key_last($args)]; + $callback = is_callable($lastArgs) ? $lastArgs : null; + + $where = is_callable($where) ? null : $where; + $columns = is_callable($columns) ? null : $columns; + + $column = $where === null ? $join : $columns; + $isSingle = (is_string($column) && $column !== '*'); + + $statement = $this->exec($this->selectContext($table, $map, $join, $columns, $where), $map); + + $this->columnMap($columns, $columnMap, true); + + if (!$this->statement) { + return $result; + } + + // @codeCoverageIgnoreStart + if ($columns === '*') { + if (isset($callback)) { + while ($data = $statement->fetch(PDO::FETCH_ASSOC)) { + $callback($data); + } + + return null; + } + + return $statement->fetchAll(PDO::FETCH_ASSOC); + } + + while ($data = $statement->fetch(PDO::FETCH_ASSOC)) { + $currentStack = []; + + if (isset($callback)) { + $this->dataMap($data, $columns, $columnMap, $currentStack, true); + + $callback( + $isSingle ? + $currentStack[$columnMap[$column][0]] : + $currentStack + ); + } else { + $this->dataMap($data, $columns, $columnMap, $currentStack, true, $result); + } + } + + if (isset($callback)) { + return null; + } + + if ($isSingle) { + $singleResult = []; + $resultKey = $columnMap[$column][0]; + + foreach ($result as $item) { + $singleResult[] = $item[$resultKey]; + } + + return $singleResult; + } + + return $result; + } + // @codeCoverageIgnoreEnd + + /** + * Insert one or more records into the table. + * + * @param string $table + * @param array $values + * @param string $primaryKey + * @return \PDOStatement|null + */ + public function insert(string $table, array $values, string $primaryKey = null): ?PDOStatement + { + $stack = []; + $columns = []; + $fields = []; + $map = []; + $returnings = []; + + if (!isset($values[0])) { + $values = [$values]; + } + + foreach ($values as $data) { + foreach ($data as $key => $value) { + $columns[] = $key; + } + } + + $columns = array_unique($columns); + + foreach ($values as $data) { + $values = []; + + foreach ($columns as $key) { + $value = $data[$key]; + $type = gettype($value); + + if ($this->type === 'oracle' && $type === 'resource') { + $values[] = 'EMPTY_BLOB()'; + $returnings[$this->mapKey()] = [$key, $value, PDO::PARAM_LOB]; + continue; + } + + if ($raw = $this->buildRaw($data[$key], $map)) { + $values[] = $raw; + continue; + } + + $mapKey = $this->mapKey(); + $values[] = $mapKey; + + switch ($type) { + + case 'array': + $map[$mapKey] = [ + strpos($key, '[JSON]') === strlen($key) - 6 ? + json_encode($value) : + serialize($value), + PDO::PARAM_STR + ]; + break; + + case 'object': + $value = serialize($value); + break; + + case 'NULL': + case 'resource': + case 'boolean': + case 'integer': + case 'double': + case 'string': + $map[$mapKey] = $this->typeMap($value, $type); + break; + } + } + + $stack[] = '(' . implode(', ', $values) . ')'; + } + + foreach ($columns as $key) { + $fields[] = $this->columnQuote(preg_replace("/(\s*\[JSON\]$)/i", '', $key)); + } + + $query = 'INSERT INTO ' . $this->tableQuote($table) . ' (' . implode(', ', $fields) . ') VALUES ' . implode(', ', $stack); + + if ( + $this->type === 'oracle' && (!empty($returnings) || isset($primaryKey)) + ) { + if ($primaryKey) { + $returnings[':RETURNID'] = [$primaryKey, '', PDO::PARAM_INT, 8]; + } + + $statement = $this->returningQuery($query, $map, $returnings); + + if ($primaryKey) { + $this->returnId = $returnings[':RETURNID'][1]; + } + + return $statement; + } + + return $this->exec($query, $map); + } + + /** + * Modify data from the table. + * + * @param string $table + * @param array $data + * @param array $where + * @return \PDOStatement|null + */ + public function update(string $table, $data, $where = null): ?PDOStatement + { + $fields = []; + $map = []; + $returnings = []; + + foreach ($data as $key => $value) { + $column = $this->columnQuote(preg_replace("/(\s*\[(JSON|\+|\-|\*|\/)\]$)/", '', $key)); + $type = gettype($value); + + if ($this->type === 'oracle' && $type === 'resource') { + $fields[] = "{$column} = EMPTY_BLOB()"; + $returnings[$this->mapKey()] = [$key, $value, PDO::PARAM_LOB]; + continue; + } + + if ($raw = $this->buildRaw($value, $map)) { + $fields[] = "{$column} = {$raw}"; + continue; + } + + preg_match('/(?[\p{L}_][\p{L}\p{N}@$#\-_]*)(\[(?\+|\-|\*|\/)\])?/u', $key, $match); + + if (isset($match['operator'])) { + if (is_numeric($value)) { + $fields[] = "{$column} = {$column} {$match['operator']} {$value}"; + } + } else { + $mapKey = $this->mapKey(); + $fields[] = "{$column} = {$mapKey}"; + + switch ($type) { + + case 'array': + $map[$mapKey] = [ + strpos($key, '[JSON]') === strlen($key) - 6 ? + json_encode($value) : + serialize($value), + PDO::PARAM_STR + ]; + break; + + case 'object': + $value = serialize($value); + + break; + case 'NULL': + case 'resource': + case 'boolean': + case 'integer': + case 'double': + case 'string': + $map[$mapKey] = $this->typeMap($value, $type); + break; + } + } + } + + $query = 'UPDATE ' . $this->tableQuote($table) . ' SET ' . implode(', ', $fields) . $this->whereClause($where, $map); + + if ($this->type === 'oracle' && !empty($returnings)) { + return $this->returningQuery($query, $map, $returnings); + } + + return $this->exec($query, $map); + } + + /** + * Delete data from the table. + * + * @param string $table + * @param array|Raw $where + * @return \PDOStatement|null + */ + public function delete(string $table, $where): ?PDOStatement + { + $map = []; + + return $this->exec('DELETE FROM ' . $this->tableQuote($table) . $this->whereClause($where, $map), $map); + } + + /** + * Replace old data with a new one. + * + * @param string $table + * @param array $columns + * @param array $where + * @return \PDOStatement|null + */ + public function replace(string $table, array $columns, $where = null): ?PDOStatement + { + $map = []; + $stack = []; + + foreach ($columns as $column => $replacements) { + if (is_array($replacements)) { + foreach ($replacements as $old => $new) { + $mapKey = $this->mapKey(); + $columnName = $this->columnQuote($column); + $stack[] = "{$columnName} = REPLACE({$columnName}, {$mapKey}a, {$mapKey}b)"; + + $map[$mapKey . 'a'] = [$old, PDO::PARAM_STR]; + $map[$mapKey . 'b'] = [$new, PDO::PARAM_STR]; + } + } + } + + if (empty($stack)) { + throw new InvalidArgumentException('Invalid columns supplied.'); + } + + return $this->exec('UPDATE ' . $this->tableQuote($table) . ' SET ' . implode(', ', $stack) . $this->whereClause($where, $map), $map); + } + + /** + * Get only one record from the table. + * + * @param string $table + * @param array $join + * @param array|string $columns + * @param array $where + * @return mixed + */ + public function get(string $table, $join = null, $columns = null, $where = null) + { + $map = []; + $result = []; + $columnMap = []; + $currentStack = []; + + if ($where === null) { + if ($this->isJoin($join)) { + $where['LIMIT'] = 1; + } else { + $columns['LIMIT'] = 1; + } + + $column = $join; + } else { + $column = $columns; + $where['LIMIT'] = 1; + } + + $isSingle = (is_string($column) && $column !== '*'); + $query = $this->exec($this->selectContext($table, $map, $join, $columns, $where), $map); + + if (!$this->statement) { + return false; + } + + // @codeCoverageIgnoreStart + $data = $query->fetchAll(PDO::FETCH_ASSOC); + + if (isset($data[0])) { + if ($column === '*') { + return $data[0]; + } + + $this->columnMap($columns, $columnMap, true); + $this->dataMap($data[0], $columns, $columnMap, $currentStack, true, $result); + + if ($isSingle) { + return $result[0][$columnMap[$column][0]]; + } + + return $result[0]; + } + } + // @codeCoverageIgnoreEnd + + /** + * Determine whether the target data existed from the table. + * + * @param string $table + * @param array $join + * @param array $where + * @return bool + */ + public function has(string $table, $join, $where = null): bool + { + $map = []; + $column = null; + + $query = $this->exec( + $this->type === 'mssql' ? + $this->selectContext($table, $map, $join, $column, $where, Medoo::raw('TOP 1 1')) : + 'SELECT EXISTS(' . $this->selectContext($table, $map, $join, $column, $where, 1) . ')', + $map + ); + + if (!$this->statement) { + return false; + } + + // @codeCoverageIgnoreStart + $result = $query->fetchColumn(); + + return $result === '1' || $result === 1 || $result === true; + } + // @codeCoverageIgnoreEnd + + /** + * Randomly fetch data from the table. + * + * @param string $table + * @param array $join + * @param array|string $columns + * @param array $where + * @return array + */ + public function rand(string $table, $join = null, $columns = null, $where = null): array + { + $orderRaw = $this->raw( + $this->type === 'mysql' ? 'RAND()' + : ($this->type === 'mssql' ? 'NEWID()' + : 'RANDOM()') + ); + + if ($where === null) { + if ($this->isJoin($join)) { + $where['ORDER'] = $orderRaw; + } else { + $columns['ORDER'] = $orderRaw; + } + } else { + $where['ORDER'] = $orderRaw; + } + + return $this->select($table, $join, $columns, $where); + } + + /** + * Build for the aggregate function. + * + * @param string $type + * @param string $table + * @param array $join + * @param string $column + * @param array $where + * @return string|null + */ + private function aggregate(string $type, string $table, $join = null, $column = null, $where = null): ?string + { + $map = []; + + $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, $type), $map); + + if (!$this->statement) { + return null; + } + + // @codeCoverageIgnoreStart + return (string) $query->fetchColumn(); + } + // @codeCoverageIgnoreEnd + + /** + * Count the number of rows from the table. + * + * @param string $table + * @param array $join + * @param string $column + * @param array $where + * @return int|null + */ + public function count(string $table, $join = null, $column = null, $where = null): ?int + { + return (int) $this->aggregate('COUNT', $table, $join, $column, $where); + } + + /** + * Calculate the average value of the column. + * + * @param string $table + * @param array $join + * @param string $column + * @param array $where + * @return string|null + */ + public function avg(string $table, $join, $column = null, $where = null): ?string + { + return $this->aggregate('AVG', $table, $join, $column, $where); + } + + /** + * Get the maximum value of the column. + * + * @param string $table + * @param array $join + * @param string $column + * @param array $where + * @return string|null + */ + public function max(string $table, $join, $column = null, $where = null): ?string + { + return $this->aggregate('MAX', $table, $join, $column, $where); + } + + /** + * Get the minimum value of the column. + * + * @param string $table + * @param array $join + * @param string $column + * @param array $where + * @return string|null + */ + public function min(string $table, $join, $column = null, $where = null): ?string + { + return $this->aggregate('MIN', $table, $join, $column, $where); + } + + /** + * Calculate the total value of the column. + * + * @param string $table + * @param array $join + * @param string $column + * @param array $where + * @return string|null + */ + public function sum(string $table, $join, $column = null, $where = null): ?string + { + return $this->aggregate('SUM', $table, $join, $column, $where); + } + + /** + * Start a transaction. + * + * @param callable $actions + * @codeCoverageIgnore + * @return void + */ + public function action(callable $actions): void + { + if (is_callable($actions)) { + $this->pdo->beginTransaction(); + + try { + $result = $actions($this); + + if ($result === false) { + $this->pdo->rollBack(); + } else { + $this->pdo->commit(); + } + } catch (Exception $e) { + $this->pdo->rollBack(); + throw $e; + } + } + } + + /** + * Return the ID for the last inserted row. + * + * @param string $name + * @codeCoverageIgnore + * @return string|null + */ + public function id(string $name = null): ?string + { + $type = $this->type; + + if ($type === 'oracle') { + return $this->returnId; + } elseif ($type === 'pgsql') { + $id = $this->pdo->query('SELECT LASTVAL()')->fetchColumn(); + + return (string) $id ?: null; + } + + return $this->pdo->lastInsertId($name); + } + + /** + * Enable debug mode and output readable statement string. + * + * @codeCoverageIgnore + * @return Medoo + */ + public function debug(): self + { + $this->debugMode = true; + + return $this; + } + + /** + * Enable debug logging mode. + * + * @codeCoverageIgnore + * @return void + */ + public function beginDebug(): void + { + $this->debugMode = true; + $this->debugLogging = true; + } + + /** + * Disable debug logging and return all readable statements. + * + * @codeCoverageIgnore + * @return void + */ + public function debugLog(): array + { + $this->debugMode = false; + $this->debugLogging = false; + + return $this->debugLogs; + } + + /** + * Return the last performed statement. + * + * @codeCoverageIgnore + * @return string|null + */ + public function last(): ?string + { + if (empty($this->logs)) { + return null; + } + + $log = $this->logs[array_key_last($this->logs)]; + + return $this->generate($log[0], $log[1]); + } + + /** + * Return all executed statements. + * + * @codeCoverageIgnore + * @return string[] + */ + public function log(): array + { + return array_map( + function ($log) { + return $this->generate($log[0], $log[1]); + }, + $this->logs + ); + } + + /** + * Get information about the database connection. + * + * @codeCoverageIgnore + * @return array + */ + public function info(): array + { + $output = [ + 'server' => 'SERVER_INFO', + 'driver' => 'DRIVER_NAME', + 'client' => 'CLIENT_VERSION', + 'version' => 'SERVER_VERSION', + 'connection' => 'CONNECTION_STATUS' + ]; + + foreach ($output as $key => $value) { + $output[$key] = @$this->pdo->getAttribute(constant('PDO::ATTR_' . $value)); + } + + $output['dsn'] = $this->dsn; + + return $output; + } +} diff --git a/php-basic-crud/server/php/Router.php b/php-basic-crud/server/php/Router.php new file mode 100644 index 00000000..b7c9ae76 --- /dev/null +++ b/php-basic-crud/server/php/Router.php @@ -0,0 +1,535 @@ + + * @copyright Copyright (c), 2013 Bram(us) Van Damme + * @license MIT public license + */ +namespace Router; + +/** + * Class Router. + */ +class Router +{ + /** + * @var array The route patterns and their handling functions + */ + private $afterRoutes = array(); + + /** + * @var array The before middleware route patterns and their handling functions + */ + private $beforeRoutes = array(); + + /** + * @var array [object|callable] The function to be executed when no route has been matched + */ + protected $notFoundCallback = []; + + /** + * @var string Current base route, used for (sub)route mounting + */ + private $baseRoute = ''; + + /** + * @var string The Request Method that needs to be handled + */ + private $requestedMethod = ''; + + /** + * @var string The Server Base Path for Router Execution + */ + private $serverBasePath; + + /** + * @var string Default Controllers Namespace + */ + private $namespace = ''; + + /** + * Store a before middleware route and a handling function to be executed when accessed using one of the specified methods. + * + * @param string $methods Allowed methods, | delimited + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function before($methods, $pattern, $fn) + { + $pattern = $this->baseRoute . '/' . trim($pattern, '/'); + $pattern = $this->baseRoute ? rtrim($pattern, '/') : $pattern; + + foreach (explode('|', $methods) as $method) { + $this->beforeRoutes[$method][] = array( + 'pattern' => $pattern, + 'fn' => $fn, + ); + } + } + + /** + * Store a route and a handling function to be executed when accessed using one of the specified methods. + * + * @param string $methods Allowed methods, | delimited + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function match($methods, $pattern, $fn) + { + $pattern = $this->baseRoute . '/' . trim($pattern, '/'); + $pattern = $this->baseRoute ? rtrim($pattern, '/') : $pattern; + + foreach (explode('|', $methods) as $method) { + $this->afterRoutes[$method][] = array( + 'pattern' => $pattern, + 'fn' => $fn, + ); + } + } + + /** + * Shorthand for a route accessed using any method. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function all($pattern, $fn) + { + $this->match('GET|POST|PUT|DELETE|OPTIONS|PATCH|HEAD', $pattern, $fn); + } + + /** + * Shorthand for a route accessed using GET. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function get($pattern, $fn) + { + $this->match('GET', $pattern, $fn); + } + + /** + * Shorthand for a route accessed using POST. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function post($pattern, $fn) + { + $this->match('POST', $pattern, $fn); + } + + /** + * Shorthand for a route accessed using PATCH. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function patch($pattern, $fn) + { + $this->match('PATCH', $pattern, $fn); + } + + /** + * Shorthand for a route accessed using DELETE. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function delete($pattern, $fn) + { + $this->match('DELETE', $pattern, $fn); + } + + /** + * Shorthand for a route accessed using PUT. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function put($pattern, $fn) + { + $this->match('PUT', $pattern, $fn); + } + + /** + * Shorthand for a route accessed using OPTIONS. + * + * @param string $pattern A route pattern such as /about/system + * @param object|callable $fn The handling function to be executed + */ + public function options($pattern, $fn) + { + $this->match('OPTIONS', $pattern, $fn); + } + + /** + * Mounts a collection of callbacks onto a base route. + * + * @param string $baseRoute The route sub pattern to mount the callbacks on + * @param callable $fn The callback method + */ + public function mount($baseRoute, $fn) + { + // Track current base route + $curBaseRoute = $this->baseRoute; + + // Build new base route string + $this->baseRoute .= $baseRoute; + + // Call the callable + call_user_func($fn); + + // Restore original base route + $this->baseRoute = $curBaseRoute; + } + + /** + * Get all request headers. + * + * @return array The request headers + */ + public function getRequestHeaders() + { + $headers = array(); + + // If getallheaders() is available, use that + if (function_exists('getallheaders')) { + $headers = getallheaders(); + + // getallheaders() can return false if something went wrong + if ($headers !== false) { + return $headers; + } + } + + // Method getallheaders() not available or went wrong: manually extract 'm + foreach ($_SERVER as $name => $value) { + if ((substr($name, 0, 5) == 'HTTP_') || ($name == 'CONTENT_TYPE') || ($name == 'CONTENT_LENGTH')) { + $headers[str_replace(array(' ', 'Http'), array('-', 'HTTP'), ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + } + } + + return $headers; + } + + /** + * Get the request method used, taking overrides into account. + * + * @return string The Request method to handle + */ + public function getRequestMethod() + { + // Take the method as found in $_SERVER + $method = $_SERVER['REQUEST_METHOD']; + + // If it's a HEAD request override it to being GET and prevent any output, as per HTTP Specification + // @url http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 + if ($_SERVER['REQUEST_METHOD'] == 'HEAD') { + ob_start(); + $method = 'GET'; + } + + // If it's a POST request, check for a method override header + elseif ($_SERVER['REQUEST_METHOD'] == 'POST') { + $headers = $this->getRequestHeaders(); + if (isset($headers['X-HTTP-Method-Override']) && in_array($headers['X-HTTP-Method-Override'], array('PUT', 'DELETE', 'PATCH'))) { + $method = $headers['X-HTTP-Method-Override']; + } + } + + return $method; + } + + /** + * Set a Default Lookup Namespace for Callable methods. + * + * @param string $namespace A given namespace + */ + public function setNamespace($namespace) + { + if (is_string($namespace)) { + $this->namespace = $namespace; + } + } + + /** + * Get the given Namespace before. + * + * @return string The given Namespace if exists + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * Execute the router: Loop all defined before middleware's and routes, and execute the handling function if a match was found. + * + * @param object|callable $callback Function to be executed after a matching route was handled (= after router middleware) + * + * @return bool + */ + public function run($callback = null) + { + // Define which method we need to handle + $this->requestedMethod = $this->getRequestMethod(); + + // Handle all before middlewares + if (isset($this->beforeRoutes[$this->requestedMethod])) { + $this->handle($this->beforeRoutes[$this->requestedMethod]); + } + + // Handle all routes + $numHandled = 0; + if (isset($this->afterRoutes[$this->requestedMethod])) { + $numHandled = $this->handle($this->afterRoutes[$this->requestedMethod], true); + } + + // If no route was handled, trigger the 404 (if any) + if ($numHandled === 0) { + $this->trigger404($this->afterRoutes[$this->requestedMethod]); + } // If a route was handled, perform the finish callback (if any) + else { + if ($callback && is_callable($callback)) { + $callback(); + } + } + + // If it originally was a HEAD request, clean up after ourselves by emptying the output buffer + if ($_SERVER['REQUEST_METHOD'] == 'HEAD') { + ob_end_clean(); + } + + // Return true if a route was handled, false otherwise + return $numHandled !== 0; + } + + /** + * Set the 404 handling function. + * + * @param object|callable|string $match_fn The function to be executed + * @param object|callable $fn The function to be executed + */ + public function set404($match_fn, $fn = null) + { + if (!is_null($fn)) { + $this->notFoundCallback[$match_fn] = $fn; + } else { + $this->notFoundCallback['/'] = $match_fn; + } + } + + /** + * Triggers 404 response + * + * @param string $pattern A route pattern such as /about/system + */ + public function trigger404($match = null){ + + // Counter to keep track of the number of routes we've handled + $numHandled = 0; + + // handle 404 pattern + if (count($this->notFoundCallback) > 0) + { + // loop fallback-routes + foreach ($this->notFoundCallback as $route_pattern => $route_callable) { + + // matches result + $matches = []; + + // check if there is a match and get matches as $matches (pointer) + $is_match = $this->patternMatches($route_pattern, $this->getCurrentUri(), $matches, PREG_OFFSET_CAPTURE); + + // is fallback route match? + if ($is_match) { + + // Rework matches to only contain the matches, not the orig string + $matches = array_slice($matches, 1); + + // Extract the matched URL parameters (and only the parameters) + $params = array_map(function ($match, $index) use ($matches) { + + // We have a following parameter: take the substring from the current param position until the next one's position (thank you PREG_OFFSET_CAPTURE) + if (isset($matches[$index + 1]) && isset($matches[$index + 1][0]) && is_array($matches[$index + 1][0])) { + if ($matches[$index + 1][0][1] > -1) { + return trim(substr($match[0][0], 0, $matches[$index + 1][0][1] - $match[0][1]), '/'); + } + } // We have no following parameters: return the whole lot + + return isset($match[0][0]) && $match[0][1] != -1 ? trim($match[0][0], '/') : null; + }, $matches, array_keys($matches)); + + $this->invoke($route_callable); + + ++$numHandled; + } + } + } + if (($numHandled == 0) && (isset($this->notFoundCallback['/']))) { + $this->invoke($this->notFoundCallback['/']); + } elseif ($numHandled == 0) { + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); + } + } + + /** + * Replace all curly braces matches {} into word patterns (like Laravel) + * Checks if there is a routing match + * + * @param $pattern + * @param $uri + * @param $matches + * @param $flags + * + * @return bool -> is match yes/no + */ + private function patternMatches($pattern, $uri, &$matches, $flags) + { + // Replace all curly braces matches {} into word patterns (like Laravel) + $pattern = preg_replace('/\/{(.*?)}/', '/(.*?)', $pattern); + + // we may have a match! + return boolval(preg_match_all('#^' . $pattern . '$#', $uri, $matches, PREG_OFFSET_CAPTURE)); + } + + /** + * Handle a a set of routes: if a match is found, execute the relating handling function. + * + * @param array $routes Collection of route patterns and their handling functions + * @param bool $quitAfterRun Does the handle function need to quit after one route was matched? + * + * @return int The number of routes handled + */ + private function handle($routes, $quitAfterRun = false) + { + // Counter to keep track of the number of routes we've handled + $numHandled = 0; + + // The current page URL + $uri = $this->getCurrentUri(); + + // Loop all routes + foreach ($routes as $route) { + + // get routing matches + $is_match = $this->patternMatches($route['pattern'], $uri, $matches, PREG_OFFSET_CAPTURE); + + // is there a valid match? + if ($is_match) { + + // Rework matches to only contain the matches, not the orig string + $matches = array_slice($matches, 1); + + // Extract the matched URL parameters (and only the parameters) + $params = array_map(function ($match, $index) use ($matches) { + + // We have a following parameter: take the substring from the current param position until the next one's position (thank you PREG_OFFSET_CAPTURE) + if (isset($matches[$index + 1]) && isset($matches[$index + 1][0]) && is_array($matches[$index + 1][0])) { + if ($matches[$index + 1][0][1] > -1) { + return trim(substr($match[0][0], 0, $matches[$index + 1][0][1] - $match[0][1]), '/'); + } + } // We have no following parameters: return the whole lot + + return isset($match[0][0]) && $match[0][1] != -1 ? trim($match[0][0], '/') : null; + }, $matches, array_keys($matches)); + + // Call the handling function with the URL parameters if the desired input is callable + $this->invoke($route['fn'], $params); + + ++$numHandled; + + // If we need to quit, then quit + if ($quitAfterRun) { + break; + } + } + } + + // Return the number of routes handled + return $numHandled; + } + + private function invoke($fn, $params = array()) + { + if (is_callable($fn)) { + call_user_func_array($fn, $params); + } + + // If not, check the existence of special parameters + elseif (stripos($fn, '@') !== false) { + // Explode segments of given route + list($controller, $method) = explode('@', $fn); + + // Adjust controller class if namespace has been set + if ($this->getNamespace() !== '') { + $controller = $this->getNamespace() . '\\' . $controller; + } + + try { + $reflectedMethod = new \ReflectionMethod($controller, $method); + // Make sure it's callable + if ($reflectedMethod->isPublic() && (!$reflectedMethod->isAbstract())) { + if ($reflectedMethod->isStatic()) { + forward_static_call_array(array($controller, $method), $params); + } else { + // Make sure we have an instance, because a non-static method must not be called statically + if (\is_string($controller)) { + $controller = new $controller(); + } + call_user_func_array(array($controller, $method), $params); + } + } + } catch (\ReflectionException $reflectionException) { + // The controller class is not available or the class does not have the method $method + } + } + } + + /** + * Define the current relative URI. + * + * @return string + */ + public function getCurrentUri() + { + // Get the current Request URI and remove rewrite base path from it (= allows one to run the router in a sub folder) + $uri = substr(rawurldecode($_SERVER['REQUEST_URI']), strlen($this->getBasePath())); + + // Don't take query params into account on the URL + if (strstr($uri, '?')) { + $uri = substr($uri, 0, strpos($uri, '?')); + } + + // Remove trailing slash + enforce a slash at the start + return '/' . trim($uri, '/'); + } + + /** + * Return server base Path, and define it if isn't defined. + * + * @return string + */ + public function getBasePath() + { + // Check if server base path is defined, if not define it. + if ($this->serverBasePath === null) { + $this->serverBasePath = implode('/', array_slice(explode('/', $_SERVER['SCRIPT_NAME']), 0, -1)) . '/'; + } + + return $this->serverBasePath; + } + + /** + * Explicilty sets the server base path. To be used when your entry script path differs from your entry URLs. + * @see https://github.com/bramus/router/issues/82#issuecomment-466956078 + * + * @param string + */ + public function setBasePath($serverBasePath) + { + $this->serverBasePath = $serverBasePath; + } +} diff --git a/php-basic-crud/server/php/Service.php b/php-basic-crud/server/php/Service.php new file mode 100644 index 00000000..42c93059 --- /dev/null +++ b/php-basic-crud/server/php/Service.php @@ -0,0 +1,29 @@ +path = strtolower(ltrim($path, '/')); + $this->method = strtolower($method); + $this->payload = $payload; + } + + public function handle(Medoo $db): ?array + { + switch ($this->path) { + case 'users'; + return (new UserController($db))->{$this->method}($this->path, $this->payload); + default: + return null; + } + } +} diff --git a/php-basic-crud/server/php/controllers/UserController.php b/php-basic-crud/server/php/controllers/UserController.php new file mode 100644 index 00000000..48b6ec15 --- /dev/null +++ b/php-basic-crud/server/php/controllers/UserController.php @@ -0,0 +1,67 @@ +db = $db; + } + + public function get(string $path, ?array $payload): ?array + { + /** + * TODO + */ + + return null; + } + + public function post(string $path, ?array $payload): ?array + { + if (empty($payload['name']) || empty($payload['email'])) { + return null; + } + + $this->db->insert('users', [ + 'name' => $payload['name'], + 'email' => $payload['email'], + ]); + + $user = $this->db->select('users', '*', [ + 'id' => $this->db->id(), + ]); + + return $user[0] ?? null; + } + + public function put(string $path, ?array $payload): ?array + { + /** + * TODO + */ + + return null; + } + + public function patch(string $path, ?array $payload): ?array + { + /** + * TODO + */ + + return null; + } + + public function delete(string $path, ?array $payload): ?array + { + /** + * TODO + */ + + return null; + } +} diff --git a/php-basic-crud/server/php/curl/Request.php b/php-basic-crud/server/php/curl/Request.php new file mode 100644 index 00000000..de84c219 --- /dev/null +++ b/php-basic-crud/server/php/curl/Request.php @@ -0,0 +1,534 @@ + + * @license http://opensource.org/licenses/MIT + * @package PHP cURL + */ + +namespace anlutro\cURL; + +/** + * cURL request representation class. + */ +class Request +{ + /** + * ENCODING_* constants, used for specifying encoding options + */ + const ENCODING_QUERY = 0; + const ENCODING_JSON = 1; + const ENCODING_RAW = 2; + + /** + * Allowed methods => allows postdata + * + * @var array + */ + public static $methods = array( + 'get' => false, + 'head' => false, + 'post' => true, + 'put' => true, + 'patch' => true, + 'delete' => true, + 'options' => false, + ); + + /** + * The HTTP method to use. Defaults to GET. + * + * @var string + */ + private $method = 'get'; + + /** + * The URL the request is sent to. + * + * @var string + */ + private $url = ''; + + /** + * The headers sent with the request. + * + * @var array + */ + private $headers = array(); + + /** + * The cookies sent with the request. + * + * @var array + */ + private $cookies = array(); + + /** + * POST data sent with the request. + * + * @var mixed + */ + private $data = array(); + + /** + * Optional cURL options. + * + * @var array + */ + private $options = array(); + + /** + * Username to authenticate the request of cURL. + * + * @var array + */ + private $user = ''; + + /** + * Password to authenticate the request of cURL. + * + * @var array + */ + private $pass = ''; + + /** + * The type of processing to perform to encode the POST data + * + * @var int + */ + private $encoding = Request::ENCODING_QUERY; + + /** + * @param cURL $curl + */ + public function __construct(cURL $curl) + { + $this->curl = $curl; + } + + /** + * Set the HTTP method of the request. + * + * @param string $method + */ + public function setMethod($method) + { + $method = strtolower($method); + + if (!array_key_exists($method, static::$methods)) { + throw new \InvalidArgumentException("Method [$method] not a valid HTTP method."); + } + + if ($this->data && !static::$methods[$method]) { + throw new \LogicException('Request has POST data, but tried changing HTTP method to one that does not allow POST data'); + } + + $this->method = $method; + + return $this; + } + + /** + * Get the HTTP method of the request. + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Set the URL of the request. + * + * @param string $url + */ + public function setUrl($url) + { + $this->url = $url; + + return $this; + } + + /** + * Get the URL of the request. + * + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * Set a specific header to be sent with the request. + * + * @param string $key Can also be a string in "foo: bar" format + * @param mixed $value + * @param boolean $preserveCase + */ + public function setHeader($key, $value = null, $preserveCase = false) + { + if ($value === null) { + list($key, $value) = explode(':', $value, 2); + } + + if (!$preserveCase) { + $key = strtolower($key); + } + + $key = trim($key); + $this->headers[$key] = trim($value); + + return $this; + } + + /** + * Set the headers to be sent with the request. + * + * Pass an associative array - e.g. ['Content-Type' => 'application/json'] + * and the correct header formatting - e.g. 'Content-Type: application/json' + * will be done for you when the request is sent. + * + * @param array $headers + */ + public function setHeaders(array $headers) + { + $this->headers = array(); + + foreach ($headers as $key => $value) { + $this->setHeader($key, $value); + } + + return $this; + } + + /** + * Get a specific header from the request. + * + * @param string $key + * + * @return mixed + */ + public function getHeader($key) + { + $key = strtolower($key); + + return isset($this->headers[$key]) ? $this->headers[$key] : null; + } + + /** + * Get the headers to be sent with the request. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Set a cookie. + * + * @param string $key + * @param string $value + */ + public function setCookie($key, $value) + { + $this->cookies[$key] = $value; + $this->updateCookieHeader(); + + return $this; + } + + /** + * Replace the request's cookies. + * + * @param array $cookies + */ + public function setCookies(array $cookies) + { + $this->cookies = $cookies; + $this->updateCookieHeader(); + + return $this; + } + + /** + * Read the request cookies and set the cookie header. + * + * @return void + */ + private function updateCookieHeader() + { + $strings = array(); + + foreach ($this->cookies as $key => $value) { + $strings[] = "{$key}={$value}"; + } + + $this->setHeader('cookie', implode('; ', $strings)); + } + + /** + * Get a specific cookie from the request. + * + * @param string $key + * + * @return string|null + */ + public function getCookie($key) + { + return isset($this->cookies[$key]) ? $this->cookies[$key] : null; + } + + /** + * Get all the request's cookies. + * + * @return string[] + */ + public function getCookies() + { + return $this->cookies; + } + + /** + * Format the headers to an array of 'key: val' which can be passed to + * curl_setopt. + * + * @return array + */ + public function formatHeaders() + { + $headers = array(); + + foreach ($this->headers as $key => $val) { + if (is_string($key)) { + $headers[] = $key . ': ' . $val; + } else { + $headers[] = $val; + } + } + + return $headers; + } + + /** + * Set the POST data to be sent with the request. + * + * @param mixed $data + */ + public function setData($data) + { + if ($data && !static::$methods[$this->method]) { + throw new \InvalidArgumentException("HTTP method [$this->method] does not allow POST data."); + } + + $this->data = $data; + + return $this; + } + + /** + * Check whether the request has any data. + * + * @return boolean + */ + public function hasData() + { + return static::$methods[$this->method] && (bool) $this->encodeData(); + } + + /** + * Get the POST data to be sent with the request. + * + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * Set the encoding to use on the POST data, and (possibly) associated Content-Type headers + * + * @param int $encoding a Request::ENCODING_* constant + */ + public function setEncoding($encoding) + { + $encoding = intval($encoding); + + if ( + $encoding !== static::ENCODING_QUERY && + $encoding !== static::ENCODING_JSON && + $encoding !== static::ENCODING_RAW + ) { + throw new \InvalidArgumentException("Encoding [$encoding] not a known Request::ENCODING_* constant"); + } + + if ($encoding === static::ENCODING_JSON && !$this->getHeader('Content-Type')) { + $this->setHeader('Content-Type', 'application/json'); + } + + $this->encoding = $encoding; + + return $this; + } + + /** + * Get the current encoding which will be used on the POST data + * + * @return int a Request::ENCODING_* constant + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Encode the POST data as a string. + * + * @return string + */ + public function encodeData() + { + switch ($this->encoding) { + case static::ENCODING_JSON: + return json_encode($this->data); + case static::ENCODING_QUERY: + return (!is_null($this->data) ? http_build_query($this->data) : ''); + case static::ENCODING_RAW: + return $this->data; + default: + $msg = "Encoding [$this->encoding] not a known Request::ENCODING_* constant"; + throw new \UnexpectedValueException($msg); + } + } + + /** + * Set a specific curl option for the request. + * + * @param int $key + * @param mixed $value + */ + public function setOption($key, $value) + { + $this->options[$key] = $value; + + return $this; + } + + /** + * Set the cURL options for the request. + * + * @param array $options + */ + public function setOptions(array $options) + { + $this->options = $options; + + return $this; + } + + /** + * Get a specific curl option from the request. + * + * @param int $key + * + * @return mixed + */ + public function getOption($key) + { + return isset($this->options[$key]) ? $this->options[$key] : null; + } + + /** + * Get the cURL options for the request. + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Set the HTTP basic username and password. + * + * @param string $user + * @param string $pass + * + * @return string + */ + public function auth($user, $pass) + { + $this->user = $user; + $this->pass = $pass; + + return $this; + } + + /** + * Set an username to authenticate the request of curl. + * + * @param string $user + * + * @return static + */ + public function setUser($user) + { + $this->user = $user; + + return $this; + } + + /** + * Set a password to authenticate the request of curl. + * + * @param string $pass + * + * @return static + */ + public function setPass($pass) + { + $this->pass = $pass; + + return $this; + } + + /** + * If username and password is set, returns a string of 'username:password'. + * If not, returns null. + * + * @return string|null + */ + public function getUserAndPass() + { + if ($this->user) { + return $this->user . ':' . $this->pass; + } + + return null; + } + + /** + * Whether the request is JSON or not. + * + * @return boolean + */ + public function isJson() + { + return $this->encoding === static::ENCODING_JSON; + } + + /** + * Send the request. + * + * @return Response + */ + public function send() + { + return $this->curl->sendRequest($this); + } +} diff --git a/php-basic-crud/server/php/curl/Response.php b/php-basic-crud/server/php/curl/Response.php new file mode 100644 index 00000000..0069960d --- /dev/null +++ b/php-basic-crud/server/php/curl/Response.php @@ -0,0 +1,245 @@ + + * @license http://opensource.org/licenses/MIT + * @package PHP cURL + */ + +namespace anlutro\cURL; + +/** + * cURL response representation class. + */ +class Response +{ + /** + * The response headers. + * + * @var array + */ + public $headers = array(); + + /** + * The response body. + * + * @var string|null + */ + public $body; + + /** + * The results of curl_getinfo on the response request. + * + * @var array|false + */ + public $info; + + /** + * The response code including text, e.g. '200 OK'. + * + * @var string + */ + public $statusText; + + /** + * The response code. + * + * @var int + */ + public $statusCode; + + /** + * @param string|null $body + * @param string $headers + * @param mixed $info + */ + public function __construct($body, $headers, $info = array()) + { + $this->body = $body; + $this->info = $info; + $this->parseHeader($headers); + } + + /** + * Parse a header string. + * + * @param string $header + * + * @return void + */ + protected function parseHeader($header) + { + if ($header === "") { + throw new \UnexpectedValueException('Empty header string passed!'); + } + $headers = explode("\r\n", trim($header)); + $this->parseHeaders($headers); + } + + /** + * Parse an array of headers. + * + * @param array $headers + * + * @return void + */ + protected function parseHeaders(array $headers) + { + if (count($headers) === 0) { + throw new \UnexpectedValueException('No headers passed!'); + } + + $this->headers = array(); + + // find and set the HTTP status code and reason + $firstHeader = array_shift($headers); + if (!preg_match('/^HTTP\/\d(\.\d)? [0-9]{3}/', $firstHeader)) { + throw new \UnexpectedValueException('Invalid response header'); + } + list(, $status) = explode(' ', $firstHeader, 2); + $code = explode(' ', $status); + $code = (int) $code[0]; + + // special handling for HTTP 100 responses + if ($code === 100) { + // remove empty header lines between 100 and actual HTTP status + foreach ($headers as $idx => $header) { + if ($header) { + break; + } + } + + // start the process over with the 100 continue header stripped away + return $this->parseHeaders(array_slice($headers, $idx)); + } + + // handle cases where CURLOPT_HTTPAUTH is being used, in which case + // curl_exec may cause two HTTP responses + if ( + array_key_exists(CURLINFO_HTTPAUTH_AVAIL, $this->info) && + $this->info[CURLINFO_HTTPAUTH_AVAIL] > 0 && + $code === 401 + ) { + $foundAuthenticateHeader = false; + $foundSecondHttpResponse = false; + foreach ($headers as $idx => $header) { + if ($foundAuthenticateHeader === false && strpos(strtolower($header), 'www-authenticate:') === 0) { + $foundAuthenticateHeader = true; + } + if ($foundAuthenticateHeader && preg_match('/^HTTP\/\d(\.\d)? [0-9]{3}/', $header)) { + $foundSecondHttpResponse = true; + break; + } + } + + // discard the original response. + if ($foundAuthenticateHeader && $foundSecondHttpResponse) { + $headers = array_slice($headers, $idx); + return $this->parseHeaders($headers); + } + } + + $this->statusText = $status; + $this->statusCode = $code; + + foreach ($headers as $header) { + // skip empty lines + if (!$header) { + continue; + } + + $delimiter = strpos($header, ':'); + if (!$delimiter) { + continue; + } + + $key = trim(strtolower(substr($header, 0, $delimiter))); + $val = ltrim(substr($header, $delimiter + 1)); + + if (isset($this->headers[$key])) { + if (is_array($this->headers[$key])) { + $this->headers[$key][] = $val; + } else { + $this->headers[$key] = array($this->headers[$key], $val); + } + } else { + $this->headers[$key] = $val; + } + } + } + + /** + * Get a specific header from the response. + * + * @param string $key + * + * @return mixed + */ + public function getHeader($key) + { + $key = strtolower($key); + + return array_key_exists($key, $this->headers) ? + $this->headers[$key] : null; + } + + /** + * Gets all the headers of the response. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Get the response body. + * + * @return string + */ + public function getBody() + { + // usually because CURLOPT_FILE is set + if ($this->body === null) { + throw new \UnexpectedValueException("Response has no body!"); + } + + return $this->body; + } + + /** + * Convert the response instance to an array. + * + * @return array + */ + public function toArray() + { + return array( + 'headers' => $this->headers, + 'body' => $this->body, + 'info' => $this->info + ); + } + + /** + * Convert the response object to a JSON string. + * + * @return string + */ + public function toJson() + { + return json_encode($this->toArray()); + } + + /** + * Convert the object to its string representation by returning the body. + * + * @return string + */ + public function __toString() + { + return (string) $this->getBody(); + } +} diff --git a/php-basic-crud/server/php/curl/cURL.php b/php-basic-crud/server/php/curl/cURL.php new file mode 100644 index 00000000..9e4ae88a --- /dev/null +++ b/php-basic-crud/server/php/curl/cURL.php @@ -0,0 +1,379 @@ + + * @license http://opensource.org/licenses/MIT + * @package PHP cURL + */ + +/** + * cURL wrapper class. + * + * @method Response get(string $url) Execute a GET request + * @method Response delete(string $url) Execute a DELETE request + * @method Response head(string $url) Execute a HEAD request + * @method Response post(string $url, mixed $data) Execute a POST request + * @method Response put(string $url, mixed $data) Execute a PUT request + * @method Response patch(string $url, mixed $data) Execute a PATCH request + * @method Response jsonGet(string $url) Execute a JSON GET request + * @method Response jsonDelete(string $url) Execute a JSON DELETE request + * @method Response jsonHead(string $url) Execute a JSON HEAD request + * @method Response jsonPost(string $url, mixed $data) Execute a JSON POST request + * @method Response jsonPut(string $url, mixed $data) Execute a JSON PUT request + * @method Response jsonPatch(string $url, mixed $data) Execute a JSON PATCH request + * @method Response rawGet(string $url) Execute a raw GET request + * @method Response rawDelete(string $url) Execute a raw DELETE request + * @method Response rawHead(string $url) Execute a raw HEAD request + * @method Response rawPost(string $url, mixed $data) Execute a raw POST request + * @method Response rawPut(string $url, mixed $data) Execute a raw PUT request + * @method Response rawPatch(string $url, mixed $data) Execute a raw PATCH request + */ +class cURL +{ + /** + * The cURL resource. + */ + protected $ch; + + /** + * The request class to use. + * + * @var string + */ + protected $requestClass = 'anlutro\cURL\Request'; + + /** + * The response class to use. + * + * @var string + */ + protected $responseClass = 'anlutro\cURL\Response'; + + /** + * The default headers. + * + * @var array + */ + protected $defaultHeaders = array(); + + /** + * The default curl options. + * + * @var array + */ + protected $defaultOptions = array(); + + /** + * Get allowed methods. + * + * @return array + */ + public function getAllowedMethods() + { + return Request::$methods; + } + + /** + * Set the request class. + * + * @param string $class + */ + public function setRequestClass($class) + { + $this->requestClass = $class; + } + + /** + * Set the response class. + * + * @param string $class + */ + public function setResponseClass($class) + { + $this->responseClass = $class; + } + + /** + * Set the default headers for every request. + * + * @param array $headers + */ + public function setDefaultHeaders(array $headers) + { + $this->defaultHeaders = $headers; + } + + /** + * Get the default headers. + * + * @return array + */ + public function getDefaultHeaders() + { + return $this->defaultHeaders; + } + + /** + * Set the default curl options for every request. + * + * @param array $options + */ + public function setDefaultOptions(array $options) + { + $this->defaultOptions = $options; + } + + /** + * Get the default options. + * + * @return array + */ + public function getDefaultOptions() + { + return $this->defaultOptions; + } + + /** + * Build an URL with an optional query string. + * + * @param string $url the base URL without any query string + * @param array $query array of GET parameters + * + * @return string + */ + public function buildUrl($url, array $query) + { + if (empty($query)) { + return $url; + } + + $parts = parse_url($url); + + $queryString = ''; + if (isset($parts['query']) && $parts['query']) { + $queryString .= $parts['query'].'&'.http_build_query($query); + } else { + $queryString .= http_build_query($query); + } + + $retUrl = $parts['scheme'].'://'.$parts['host']; + if (isset($parts['port'])) { + $retUrl .= ':'.$parts['port']; + } + + if (isset($parts['path'])) { + $retUrl .= $parts['path']; + } + + if ($queryString) { + $retUrl .= '?' . $queryString; + } + + return $retUrl; + } + + /** + * Create a new response object and set its values. + * + * @param string $method get, post, etc + * @param string $url + * @param mixed $data POST data + * @param int $encoding Request::ENCODING_* constant specifying how to process the POST data + * + * @return Request + */ + public function newRequest($method, $url, $data = array(), $encoding = Request::ENCODING_QUERY) + { + $class = $this->requestClass; + $request = new $class($this); + + if ($this->defaultHeaders) { + $request->setHeaders($this->defaultHeaders); + } + if ($this->defaultOptions) { + $request->setOptions($this->defaultOptions); + } + $request->setMethod($method); + $request->setUrl($url); + $request->setData($data); + $request->setEncoding($encoding); + + return $request; + } + + /** + * Create a new JSON request and set its values. + * + * @param string $method get, post etc + * @param string $url + * @param mixed $data POST data + * + * @return Request + */ + public function newJsonRequest($method, $url, $data = array()) + { + return $this->newRequest($method, $url, $data, Request::ENCODING_JSON); + } + + /** + * Create a new raw request and set its values. + * + * @param string $method get, post etc + * @param string $url + * @param mixed $data request body + * + * @return Request + */ + public function newRawRequest($method, $url, $data = '') + { + return $this->newRequest($method, $url, $data, Request::ENCODING_RAW); + } + + /** + * Prepare the curl resource for sending a request. + * + * @param Request $request + * + * @return void + */ + public function prepareRequest(Request $request) + { + $this->ch = curl_init(); + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->ch, CURLOPT_HEADER, true); + if ($auth = $request->getUserAndPass()) { + curl_setopt($this->ch, CURLOPT_USERPWD, $auth); + } + curl_setopt($this->ch, CURLOPT_URL, $request->getUrl()); + + $options = $request->getOptions(); + if (!empty($options)) { + curl_setopt_array($this->ch, $options); + } + + $method = $request->getMethod(); + curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, strtoupper($method)); + + curl_setopt($this->ch, CURLOPT_HTTPHEADER, $request->formatHeaders()); + + if ($request->hasData()) { + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $request->encodeData()); + } + + if ($method === 'head') { + curl_setopt($this->ch, CURLOPT_NOBODY, true); + } + } + + /** + * Send a request. + * + * @param Request $request + * + * @return Response + */ + public function sendRequest(Request $request) + { + $this->prepareRequest($request); + + $result = curl_exec($this->ch); + + if ($result === false) { + $errno = curl_errno($this->ch); + $errmsg = curl_error($this->ch); + $msg = "cURL request failed with error [$errno]: $errmsg"; + curl_close($this->ch); + throw new cURLException($request, $msg, $errno); + } + + $response = $this->createResponseObject($result, $request); + + curl_close($this->ch); + + return $response; + } + + /** + * Extract the response info, header and body from a cURL response. Saves + * the data in variables stored on the object. + * + * @param string $response + * @param Request $request + * + * @return Response + */ + protected function createResponseObject($response, Request $request) + { + $info = curl_getinfo($this->ch); + $headerSize = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE); + // needed for the Response class to know that it may have to parse 2 HTTP responses + $info[CURLINFO_HTTPAUTH_AVAIL] = curl_getinfo($this->ch, CURLINFO_HTTPAUTH_AVAIL); + + if ($file = $request->getOption(CURLOPT_FILE)) { + // file may be opened write-only, and even when it isn't, + // seeking/reading seems to be buggy + $fileMeta = stream_get_meta_data($file); + $file = fopen($fileMeta['uri'], 'r'); + $headers = fread($file, $headerSize); + fclose($file); + $body = null; + } else { + $headers = substr($response, 0, $headerSize); + $body = substr($response, $headerSize); + } + + $class = $this->responseClass; + + return new $class($body, $headers, $info); + } + + /** + * Handle dynamic calls to the class. + * + * @param string $func + * @param array $args + * + * @return mixed + */ + public function __call($func, $args) + { + $method = strtolower($func); + + $encoding = Request::ENCODING_QUERY; + + if (substr($method, 0, 4) === 'json') { + $encoding = Request::ENCODING_JSON; + $method = substr($method, 4); + } elseif (substr($method, 0, 3) === 'raw') { + $encoding = Request::ENCODING_RAW; + $method = substr($method, 3); + } + + if (!array_key_exists($method, Request::$methods)) { + throw new \BadMethodCallException("Method [$method] not a valid HTTP method."); + } + + if (!isset($args[0])) { + throw new \BadMethodCallException('Missing argument 1 ($url) for '.__CLASS__.'::'.$func); + } + $url = $args[0]; + + if (isset($args[1])) { + $data = $args[1]; + } else { + $data = null; + } + + $request = $this->newRequest($method, $url, $data, $encoding); + + return $this->sendRequest($request); + } +} diff --git a/php-basic-crud/server/php/curl/cURLException.php b/php-basic-crud/server/php/curl/cURLException.php new file mode 100644 index 00000000..4974a1ec --- /dev/null +++ b/php-basic-crud/server/php/curl/cURLException.php @@ -0,0 +1,46 @@ + + * @license http://opensource.org/licenses/MIT + * @package PHP cURL + */ + +namespace anlutro\cURL; + +use Exception; +use RuntimeException; + +class cURLException extends RuntimeException +{ + /** + * The request that triggered the exception. + * + * @var Request + */ + protected $request; + + /** + * Constructor. + * + * @param Request|null $request + * @param string $message + * @param integer $code + */ + public function __construct(Request $request, $message = "", $code = 0) + { + parent::__construct($message, $code); + $this->request = $request; + } + + /** + * Get the request that triggered the exception. + * + * @return Request + */ + public function getRequest() + { + return $this->request; + } +} diff --git a/php-basic-crud/server/php/index.php b/php-basic-crud/server/php/index.php new file mode 100644 index 00000000..42235876 --- /dev/null +++ b/php-basic-crud/server/php/index.php @@ -0,0 +1,43 @@ +post('/advance', function () use ($app) { + http_response_code(202); + + $payload = json_decode( + file_get_contents('php://input'), + true, + 512, + JSON_THROW_ON_ERROR + ); + + $data = null; + + if (isset($payload['payload'])) { + $data = json_decode( + hex2bin( + ltrim($payload['payload'], '0x') + ), + true, + 512, + JSON_THROW_ON_ERROR + ); + } + + $app->handleAdvance($data); +}); + +$router->get('/inspect', function () use ($app) { + $app->handleInspect($_GET); +}); + +$router->run(); + diff --git a/php-basic-crud/server/run-machine-console.sh b/php-basic-crud/server/run-machine-console.sh new file mode 100755 index 00000000..9bbd7ae6 --- /dev/null +++ b/php-basic-crud/server/run-machine-console.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +cartesi-machine \ + --ram-length=128Mi \ + --rollup \ + --flash-drive=label:php-basic-crud-dapp,filename:php-basic-crud-dapp.ext2 \ + --flash-drive=label:root,filename:rootfs.ext2 \ + --ram-image=linux-5.5.19-ctsi-3.bin \ + --rom-image=rom.bin \ + -i \ + -- "/bin/sh" diff --git a/php-basic-crud/server/run.sh b/php-basic-crud/server/run.sh new file mode 100755 index 00000000..dc9be562 --- /dev/null +++ b/php-basic-crud/server/run.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +# Start the Cartesi HTTP-Dispatcher and the php-basic-crud-dapp. +# This script must run inside the cartesi machine + +DAPP_PORT=5003 +HTTP_DISPATCHER_PORT=5004 + +# Change dir to php-basic-crud-dapp root +cd /mnt/php-basic-crud-dapp + +# Start php-basic-crud dapp +echo -n "Starting php-basic-crud-dapp: " +php -S 127.0.0.1:$DAPP_PORT -t php & + +# Wait for the php-basic-crud dapp to start up +RETRY=0 +while ! netstat -ntl 2&>1 | grep $DAPP_PORT > /dev/null +do + echo -n "." + sleep 1 + RETRY=$(echo $RETRY + 1 | bc) + if [ "$RETRY" == "20" ] + then + echo "php-basic-crud dapp timed out" + return 1 + fi +done +echo "" + +# Start http dispatcher +echo "Starting http-dispatcher: " +http-dispatcher --address 127.0.0.1:$HTTP_DISPATCHER_PORT --dapp 127.0.0.1:$DAPP_PORT --verbose diff --git a/php-basic-crud/server/shasumfile b/php-basic-crud/server/shasumfile new file mode 100644 index 00000000..e3d69c87 --- /dev/null +++ b/php-basic-crud/server/shasumfile @@ -0,0 +1,3 @@ +79b031a7dc04c5776dd7839d6a0777ae594702f4 *rom.bin +eda00d337a8dbb1d4b644dc5c6b8c3dc83e8617d *rootfs.ext2 +77a3d70300de74e1db0a7c43573e6f10a970abb6 *linux-5.5.19-ctsi-3.bin From 47f7e0a320cbcd83aec76bc4e066493e9031528f Mon Sep 17 00:00:00 2001 From: Karol Pietruszka Date: Mon, 18 Jul 2022 14:34:35 +0200 Subject: [PATCH 2/2] echo js --- .idea/.gitignore | 8 + .idea/inspectionProfiles/Project_Default.xml | 128 ++++ .idea/modules.xml | 8 + .idea/php.xml | 6 + .idea/rollups-examples-clean.iml | 8 + .idea/vcs.xml | 6 + echo-js/Dockerfile | 5 + echo-js/README.md | 157 +++++ echo-js/config/bs-config.toml | 10 + echo-js/config/indexer-config.toml | 15 + echo-js/config/logic-config.toml | 23 + echo-js/config/sf-config.toml | 13 + echo-js/config/tm-config.toml | 10 + echo-js/dapp.json | 8 + echo-js/deploy-testnet.yml | 32 + echo-js/deployments/localhost/.chainId | 1 + echo-js/deployments/localhost/Bank.json | 239 ++++++++ echo-js/deployments/localhost/Bitmask.json | 49 ++ .../localhost/BitsManipulation.json | 165 ++++++ .../localhost/CartesiDAppFactory.json | 477 +++++++++++++++ .../deployments/localhost/CartesiMath.json | 218 +++++++ .../deployments/localhost/CartesiToken.json | 536 +++++++++++++++++ .../localhost/DiamondCutFacet.json | 135 +++++ .../deployments/localhost/DiamondInit.json | 176 ++++++ .../localhost/DiamondLoupeFacet.json | 177 ++++++ .../localhost/ERC20PortalFacet.json | 121 ++++ .../localhost/ERC721PortalFacet.json | 190 ++++++ .../localhost/EtherPortalFacet.json | 153 +++++ .../localhost/FeeManagerFacet.json | 198 +++++++ echo-js/deployments/localhost/InputFacet.json | 187 ++++++ .../deployments/localhost/LibClaimsMask.json | 40 ++ echo-js/deployments/localhost/LibDiamond.json | 102 ++++ .../localhost/LibDisputeManager.json | 40 ++ .../deployments/localhost/LibFeeManager.json | 81 +++ echo-js/deployments/localhost/LibInput.json | 94 +++ echo-js/deployments/localhost/LibOutput.json | 40 ++ echo-js/deployments/localhost/LibRollups.json | 129 ++++ .../localhost/LibValidatorManager.json | 118 ++++ echo-js/deployments/localhost/Merkle.json | 222 +++++++ .../deployments/localhost/MineTimelock.json | 241 ++++++++ .../deployments/localhost/OutputFacet.json | 448 ++++++++++++++ .../deployments/localhost/OwnershipFacet.json | 105 ++++ .../deployments/localhost/RollupsFacet.json | 295 ++++++++++ .../deployments/localhost/SimpleFaucet.json | 114 ++++ .../localhost/ValidatorManagerFacet.json | 294 ++++++++++ .../localhost/WorkerAuthManagerImpl.json | 255 ++++++++ .../WorkerManagerAuthManagerImpl.json | 553 ++++++++++++++++++ .../localhost/WorkerManagerImpl.json | 373 ++++++++++++ echo-js/deployments/localhost/dapp.address | 1 + .../853463bf44733f3d929a32fa4eacb9e6.json | 203 +++++++ echo-js/docker-bake.hcl | 43 ++ echo-js/docker-bake.override.hcl | 15 + echo-js/docker-compose.override.yml | 5 + echo-js/docker/Dockerfile | 134 +++++ echo-js/docker/build-dapp-fs.sh | 35 ++ echo-js/docker/build-machine.sh | 29 + echo-js/docker/default.json | 17 + echo-js/docker/dependencies | 3 + echo-js/docker/run-machine-console.sh | 22 + echo-js/docker/shasumfile | 3 + echo-js/entrypoint.sh | 15 + echo-js/server/src/echo-server.js | 81 +++ echo-js/server/src/modules/fetch.js | 150 +++++ 63 files changed, 7759 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/php.xml create mode 100644 .idea/rollups-examples-clean.iml create mode 100644 .idea/vcs.xml create mode 100644 echo-js/Dockerfile create mode 100644 echo-js/README.md create mode 100644 echo-js/config/bs-config.toml create mode 100644 echo-js/config/indexer-config.toml create mode 100644 echo-js/config/logic-config.toml create mode 100644 echo-js/config/sf-config.toml create mode 100644 echo-js/config/tm-config.toml create mode 100644 echo-js/dapp.json create mode 100644 echo-js/deploy-testnet.yml create mode 100644 echo-js/deployments/localhost/.chainId create mode 100644 echo-js/deployments/localhost/Bank.json create mode 100644 echo-js/deployments/localhost/Bitmask.json create mode 100644 echo-js/deployments/localhost/BitsManipulation.json create mode 100644 echo-js/deployments/localhost/CartesiDAppFactory.json create mode 100644 echo-js/deployments/localhost/CartesiMath.json create mode 100644 echo-js/deployments/localhost/CartesiToken.json create mode 100644 echo-js/deployments/localhost/DiamondCutFacet.json create mode 100644 echo-js/deployments/localhost/DiamondInit.json create mode 100644 echo-js/deployments/localhost/DiamondLoupeFacet.json create mode 100644 echo-js/deployments/localhost/ERC20PortalFacet.json create mode 100644 echo-js/deployments/localhost/ERC721PortalFacet.json create mode 100644 echo-js/deployments/localhost/EtherPortalFacet.json create mode 100644 echo-js/deployments/localhost/FeeManagerFacet.json create mode 100644 echo-js/deployments/localhost/InputFacet.json create mode 100644 echo-js/deployments/localhost/LibClaimsMask.json create mode 100644 echo-js/deployments/localhost/LibDiamond.json create mode 100644 echo-js/deployments/localhost/LibDisputeManager.json create mode 100644 echo-js/deployments/localhost/LibFeeManager.json create mode 100644 echo-js/deployments/localhost/LibInput.json create mode 100644 echo-js/deployments/localhost/LibOutput.json create mode 100644 echo-js/deployments/localhost/LibRollups.json create mode 100644 echo-js/deployments/localhost/LibValidatorManager.json create mode 100644 echo-js/deployments/localhost/Merkle.json create mode 100644 echo-js/deployments/localhost/MineTimelock.json create mode 100644 echo-js/deployments/localhost/OutputFacet.json create mode 100644 echo-js/deployments/localhost/OwnershipFacet.json create mode 100644 echo-js/deployments/localhost/RollupsFacet.json create mode 100644 echo-js/deployments/localhost/SimpleFaucet.json create mode 100644 echo-js/deployments/localhost/ValidatorManagerFacet.json create mode 100644 echo-js/deployments/localhost/WorkerAuthManagerImpl.json create mode 100644 echo-js/deployments/localhost/WorkerManagerAuthManagerImpl.json create mode 100644 echo-js/deployments/localhost/WorkerManagerImpl.json create mode 100644 echo-js/deployments/localhost/dapp.address create mode 100644 echo-js/deployments/localhost/solcInputs/853463bf44733f3d929a32fa4eacb9e6.json create mode 100644 echo-js/docker-bake.hcl create mode 100644 echo-js/docker-bake.override.hcl create mode 100644 echo-js/docker-compose.override.yml create mode 100644 echo-js/docker/Dockerfile create mode 100755 echo-js/docker/build-dapp-fs.sh create mode 100755 echo-js/docker/build-machine.sh create mode 100644 echo-js/docker/default.json create mode 100644 echo-js/docker/dependencies create mode 100755 echo-js/docker/run-machine-console.sh create mode 100644 echo-js/docker/shasumfile create mode 100755 echo-js/entrypoint.sh create mode 100644 echo-js/server/src/echo-server.js create mode 100644 echo-js/server/src/modules/fetch.js diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..b498a8d7 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,128 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..6c19506a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 00000000..0e09af40 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/rollups-examples-clean.iml b/.idea/rollups-examples-clean.iml new file mode 100644 index 00000000..c956989b --- /dev/null +++ b/.idea/rollups-examples-clean.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/echo-js/Dockerfile b/echo-js/Dockerfile new file mode 100644 index 00000000..84aa72f5 --- /dev/null +++ b/echo-js/Dockerfile @@ -0,0 +1,5 @@ +# syntax=docker.io/docker/dockerfile:1.4 +FROM cartesi/toolchain:0.10.0 as dapp-build + +WORKDIR /opt/cartesi/dapp +COPY . . diff --git a/echo-js/README.md b/echo-js/README.md new file mode 100644 index 00000000..be3048a3 --- /dev/null +++ b/echo-js/README.md @@ -0,0 +1,157 @@ +# echo-js DApp + +echo-js is a customized DApp written in Javascript, which originally resembles the one provided by the sample [Echo Python DApp](https://github.com/cartesi/rollups-examples/tree/main/echo-python). + +The documentation below reflects the original application code, and should also be used as a basis for documenting any DApp created with this mechanism. + +## Requirements + +Please refer to the [rollups-examples requirements](https://github.com/cartesi/rollups-examples/tree/main/README.md#requirements). + +## Building + +To build the application, run the following command: + +```shell +docker buildx bake -f docker-bake.hcl -f docker-bake.override.hcl --load +``` + +## Running + +To start the application, execute the following command: + +```shell +docker compose -f ../docker-compose.yml -f ./docker-compose.override.yml up +``` + +The application can afterwards be shut down with the following command: + +```shell +docker compose -f ../docker-compose.yml -f ./docker-compose.override.yml down -v +``` + +## Interacting with the application + +We can use the rollups-examples [frontend-console](https://github.com/cartesi/rollups-examples/tree/main/frontend-console) application to interact with the DApp. +Ensure that the [application has already been built](https://github.com/cartesi/rollups-examples/tree/main/frontend-console/README.md#building) before using it. + +From within the `frontend-console` directory, you can send an input as follows: + +```shell +yarn start send --input "Hello there" +``` + +In order to verify the notices generated by your inputs, run the command: + +```shell +yarn start notices +``` + +The response should be something like this: + +```shell +[ { epoch: '0', input: '1', notice: '0', payload: 'Hello there' } ] +``` + +## Deploying to a testnet + +Deploying the application to a blockchain requires creating a smart contract on that network, as well as running a validator node for the DApp. + +The first step is to build the DApp's back-end machine, which will produce a hash that serves as a unique identifier. + +```shell +docker buildx bake -f docker-bake.hcl -f docker-bake.override.hcl machine --load +``` + +Once the machine docker image is ready, we can use it to deploy a corresponding Rollups smart contract. This requires you to define a few environment variables to specify which network you are deploying to, which account to use, and which RPC gateway to use when submitting the deploy transaction. + +```shell +export NETWORK= +export MNEMONIC= +export RPC_URL= +``` + +For example, to deploy to the Goerli testnet using an Alchemy RPC node, you could execute: + +```shell +export NETWORK=goerli +export MNEMONIC= +export RPC_URL=https://eth-goerli.alchemyapi.io/v2/ +``` + +With that in place, you can submit a deploy transaction to the Cartesi DApp Factory contract on the target network by executing the following command: + +```shell +DAPP_NAME=echo-js docker compose -f ./deploy-testnet.yml up +``` + +This will create a file at `./deployments//echo-js.address` with the deployed contract's address. +Once the command finishes, it is advisable to stop the docker compose and remove the volumes created when executing it. + +```shell +DAPP_NAME=echo-js docker compose -f ./deploy-testnet.yml down -v +``` + +After that, a corresponding Cartesi Validator Node must also be instantiated in order to interact with the deployed smart contract on the target network and handle the back-end logic of the DApp. +Aside from the environment variables defined above, the node will also need a secure websocket endpoint for the RPC gateway (WSS URL) and the chain ID of the target network. + +For example, for Goerli and Alchemy, you would set the following additional variables: + +```shell +export WSS_URL=wss://eth-goerli.alchemyapi.io/v2/ +export CHAIN_ID=5 +``` + +Then, the node itself can be started by running a docker compose as follows: + +```shell +DAPP_NAME=mydapp docker compose -f ./docker-compose-testnet.yml -f ./docker-compose.override.yml up +``` + +## Interacting with the deployed application + +With the node running, you can interact with the deployed DApp using the [frontend-console](https://github.com/cartesi/rollups-examples/tree/main/frontend-console), as described [previously](#interacting-with-the-application). +This time, however, you need to specify the appropriate connectivity configurations. + +First of all, in the separate terminal for the frontend-console, define the `MNEMONIC` and `RPC_URL` variables as before: + +```shell +export MNEMONIC= +export RPC_URL= +``` + +Then, inputs can be sent by specifying the DApp contract's address, as follows: + +```shell +yarn start send --input "Hello there" --addressFile path/to/echo-js/deployments//echo-js.address +``` + +Resulting notices can then be retrieved by querying the local Cartesi Node, as before: + +```shell +yarn start notices +``` + +## Running the back-end in host mode + +When developing an application, it is often important to easily test and debug it. For that matter, it is possible to run the Cartesi Rollups environment in [host mode](https://github.com/cartesi/rollups-examples/tree/main/README.md#host-mode), so that the DApp's back-end can be executed directly on the host machine, allowing it to be debugged using regular development tools such as an IDE. + +This DApp's back-end is written in `Javascript` that using `QuickJS` engine, so to run it in your machine you need to have `QuickJS` installed. + +In order to start the back-end, run the following commands in a dedicated terminal: + +```shell +# DIR ../echo-js/ +ROLLUP_HTTP_SERVER_URL="http://127.0.0.1:5004" qjs server/src/echo-server.js +``` + +The final command will effectively run the back-end and send corresponding outputs to port `5004`. + +After the back-end successfully starts, it should print an output like the following: + +```log +HTTP rollup_server url is http://127.0.0.1:5004 +Sending finish +``` + +After that, you can interact with the application normally [as explained above](#interacting-with-the-application). diff --git a/echo-js/config/bs-config.toml b/echo-js/config/bs-config.toml new file mode 100644 index 00000000..2ae813e6 --- /dev/null +++ b/echo-js/config/bs-config.toml @@ -0,0 +1,10 @@ +[block_subscriber] + +# max delay between retries in seconds +max_delay = 64 + +# max number of retries +max_retries = 5 + +# timeout for block subscriber in seconds +timeout = 120 diff --git a/echo-js/config/indexer-config.toml b/echo-js/config/indexer-config.toml new file mode 100644 index 00000000..0ed19efa --- /dev/null +++ b/echo-js/config/indexer-config.toml @@ -0,0 +1,15 @@ +[indexer_config] + +# unique session identifier for machine manager +session_id = "default_rollups_id" + +# node starts syncing from inital epoch +initial_epoch = 0 + +# polling interval +interval = 10 + +# end points +postgres_endpoint = "postgres://postgres:password@database/postgres" +state_server_endpoint = "http://state_server:50051" +mm_endpoint = "http://server_manager:5001" diff --git a/echo-js/config/logic-config.toml b/echo-js/config/logic-config.toml new file mode 100644 index 00000000..46535525 --- /dev/null +++ b/echo-js/config/logic-config.toml @@ -0,0 +1,23 @@ +[logic_config] + +# unique session identifier for machine manager +session_id = "default_rollups_id" + +# node starts syncing from inital epoch +initial_epoch = 0 + +# gas estimation/price multiplier +gas_multiplier = 1 +gas_price_multiplier = 1 + +# number of blocks before resubmting tx +rate = 20 + +# depth of blocks before considering tx finalized +confirmations = 10 + +# end points +provider_http_endpoint = "http://hardhat:8545" +ws_endpoint = "ws://hardhat:8545" +state_fold_grpc_endpoint = "http://state_server:50051" +mm_endpoint = "http://server_manager:5001" diff --git a/echo-js/config/sf-config.toml b/echo-js/config/sf-config.toml new file mode 100644 index 00000000..a28d8eb8 --- /dev/null +++ b/echo-js/config/sf-config.toml @@ -0,0 +1,13 @@ +[state_fold] + +# concurrent events fetch for state fold access +concurrent_events_fetch = 16 + +# genesis block number for state fold access +genesis_block = "0x1" + +# query limit error for state fold access +query_limit_error_codes = [-32005] + +# number of blocks (depth) before considering state finalized +safety_margin = 0 diff --git a/echo-js/config/tm-config.toml b/echo-js/config/tm-config.toml new file mode 100644 index 00000000..24c5727f --- /dev/null +++ b/echo-js/config/tm-config.toml @@ -0,0 +1,10 @@ +[tx_manager] + +# max delay between retries in seconds +max_delay = 64 + +# max number of retries +max_retries = 5 + +# timeout for a sent transaction in seconds +transaction_timeout = 5 diff --git a/echo-js/dapp.json b/echo-js/dapp.json new file mode 100644 index 00000000..597c7969 --- /dev/null +++ b/echo-js/dapp.json @@ -0,0 +1,8 @@ +{ + "fs": { + "files": [ + "server", + "entrypoint.sh" + ] + } +} diff --git a/echo-js/deploy-testnet.yml b/echo-js/deploy-testnet.yml new file mode 100644 index 00000000..66596abf --- /dev/null +++ b/echo-js/deploy-testnet.yml @@ -0,0 +1,32 @@ +version: "3.9" + +services: + machine: + image: cartesi/dapp:${DAPP_NAME:?undefined DAPP_NAME}-devel-machine + command: xxd -c 256 -p hash; sleep 3 + volumes: + - machine:/opt/cartesi/share/dapp-bin + + deployer: + image: cartesi/rollups-cli:0.3.0 + depends_on: + machine: + condition: service_started + command: + [ + "create", + "--rpc", + "${RPC_URL:?undefined RPC_URL}", + "--mnemonic", + "${MNEMONIC:?undefined MNEMONIC}", + "--templateHashFile", + "/opt/cartesi/share/dapp-bin/hash", + "--outputFile", + "/deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.address", + ] + volumes: + - machine:/opt/cartesi/share/dapp-bin:ro + - ./deployments:/deployments + +volumes: + machine: {} diff --git a/echo-js/deployments/localhost/.chainId b/echo-js/deployments/localhost/.chainId new file mode 100644 index 00000000..027791f4 --- /dev/null +++ b/echo-js/deployments/localhost/.chainId @@ -0,0 +1 @@ +31337 \ No newline at end of file diff --git a/echo-js/deployments/localhost/Bank.json b/echo-js/deployments/localhost/Bank.json new file mode 100644 index 00000000..175fe87c --- /dev/null +++ b/echo-js/deployments/localhost/Bank.json @@ -0,0 +1,239 @@ +{ + "address": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "depositTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "transferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xc21d4634243103d1e2f07d9000244ebab6b75ffa6b0728b40c5d0eb554af2a65", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E", + "transactionIndex": 0, + "gasUsed": "337439", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3f9310e49ca623e973fc2d1ac5b83a9104434d09c8a11e290b441ca674ab60b5", + "transactionHash": "0xc21d4634243103d1e2f07d9000244ebab6b75ffa6b0728b40c5d0eb554af2a65", + "logs": [], + "blockNumber": 31, + "cumulativeGasUsed": "337439", + "status": 1, + "byzantium": true + }, + "args": [ + "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" + ], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"depositTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"balanceOf(address)\":{\"params\":{\"_owner\":\"account owner\"}},\"depositTokens(address,uint256)\":{\"details\":\"you may need to call `token.approve(bank, _value)`\",\"params\":{\"_to\":\"account that will have their balance increased by `_value`\",\"_value\":\"amount of tokens to be transfered\"}},\"transferTokens(address,uint256)\":{\"params\":{\"_to\":\"account that will receive `_value` tokens\",\"_value\":\"amount of tokens to be transfered\"}}},\"version\":1},\"userdoc\":{\"events\":{\"Deposit(address,address,uint256)\":{\"notice\":\"`value` tokens were transfered from `from` to bankthe balance of `to` was increased by `value`\"},\"Transfer(address,address,uint256)\":{\"notice\":\"`value` tokens were transfered from the bank to `to`the balance of `from` was decreased by `value`\"}},\"kind\":\"user\",\"methods\":{\"balanceOf(address)\":{\"notice\":\"get balance of `_owner`\"},\"depositTokens(address,uint256)\":{\"notice\":\"transfer `_value` tokens from caller to bankincrease the balance of `_to` by `_value`\"},\"getToken()\":{\"notice\":\"returns the token used internally\"},\"transferTokens(address,uint256)\":{\"notice\":\"transfer `_value` tokens from bank to `_to`decrease the balance of caller by `_value`\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bank.sol\":\"Bank\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/Bank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank contract\\npragma solidity ^0.8.0;\\n\\nimport {IBank} from \\\"./IBank.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ncontract Bank is IBank {\\n IERC20 private immutable token;\\n\\n // `balances` maps account/contract addresses to balances\\n mapping(address => uint256) private balances;\\n\\n constructor(address _token) {\\n require(_token != address(0), \\\"Bank: invalid token\\\");\\n token = IERC20(_token);\\n }\\n\\n function getToken() public view override returns (IERC20) {\\n return token;\\n }\\n\\n function balanceOf(address _owner) public view override returns (uint256) {\\n return balances[_owner];\\n }\\n\\n function transferTokens(address _to, uint256 _value) public override {\\n // checks\\n uint256 balance = balances[msg.sender];\\n require(_value <= balance, \\\"Bank: not enough balance\\\");\\n\\n // effects\\n // Note: this should not underflow because we checked that\\n // `_value <= balance` in the `require` above\\n unchecked {\\n balances[msg.sender] = balance - _value;\\n }\\n\\n // interactions\\n // Note: a well-implemented ERC-20 contract should already\\n // require the recipient (in this case, `_to`) to be different\\n // than address(0), so we don't need to check it ourselves\\n require(token.transfer(_to, _value), \\\"Bank: transfer failed\\\");\\n emit Transfer(msg.sender, _to, _value);\\n }\\n\\n function depositTokens(address _to, uint256 _value) public override {\\n // checks\\n require(_to != address(0), \\\"Bank: invalid recipient\\\");\\n\\n // effects\\n // Note: this should not overflow because `IERC20.totalSupply`\\n // returns a `uint256` value, so there can't be more than\\n // `uint256.max` tokens in an ERC-20 contract.\\n balances[_to] += _value;\\n\\n // interactions\\n // Note: transfers tokens to bank, but emits `Deposit` event\\n // with recipient being `_to`\\n require(\\n token.transferFrom(msg.sender, address(this), _value),\\n \\\"Bank: transferFrom failed\\\"\\n );\\n emit Deposit(msg.sender, _to, _value);\\n }\\n}\\n\",\"keccak256\":\"0x1a0ebcbd1c823c592b224959a3b9c4603489c4a3d878b2809c6552528fed672b\",\"license\":\"Apache-2.0\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161060b38038061060b83398101604081905261002f9161009a565b6001600160a01b0381166100895760405162461bcd60e51b815260206004820152601360248201527f42616e6b3a20696e76616c696420746f6b656e00000000000000000000000000604482015260640160405180910390fd5b6001600160a01b03166080526100ca565b6000602082840312156100ac57600080fd5b81516001600160a01b03811681146100c357600080fd5b9392505050565b6080516105196100f260003960008181605e01528181610196015261033901526105196000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806321df0da71461005157806366168bd71461008d57806370a08231146100a2578063bec3fa17146100d9575b600080fd5b6040516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020015b60405180910390f35b6100a061009b36600461044f565b6100ec565b005b6100cb6100b0366004610479565b6001600160a01b031660009081526020819052604090205490565b604051908152602001610084565b6100a06100e736600461044f565b61029f565b6001600160a01b0382166101475760405162461bcd60e51b815260206004820152601760248201527f42616e6b3a20696e76616c696420726563697069656e7400000000000000000060448201526064015b60405180910390fd5b6001600160a01b0382166000908152602081905260408120805483929061016f90849061049b565b90915550506040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303816000875af11580156101e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020b91906104c1565b6102575760405162461bcd60e51b815260206004820152601960248201527f42616e6b3a207472616e7366657246726f6d206661696c656400000000000000604482015260640161013e565b60408051338152602081018390526001600160a01b038416917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62910160405180910390a25050565b33600090815260208190526040902054808211156102ff5760405162461bcd60e51b815260206004820152601860248201527f42616e6b3a206e6f7420656e6f7567682062616c616e63650000000000000000604482015260640161013e565b336000908152602081905260409081902083830390555163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015610382573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a691906104c1565b6103ea5760405162461bcd60e51b815260206004820152601560248201527410985b9ace881d1c985b9cd9995c8819985a5b1959605a1b604482015260640161013e565b604080516001600160a01b03851681526020810184905233917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a2505050565b80356001600160a01b038116811461044a57600080fd5b919050565b6000806040838503121561046257600080fd5b61046b83610433565b946020939093013593505050565b60006020828403121561048b57600080fd5b61049482610433565b9392505050565b600082198211156104bc57634e487b7160e01b600052601160045260246000fd5b500190565b6000602082840312156104d357600080fd5b8151801515811461049457600080fdfea26469706673582212202f52a7f24915f76bd55f8533504eca6464ea1199be7010f33418e3e3cb53374564736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806321df0da71461005157806366168bd71461008d57806370a08231146100a2578063bec3fa17146100d9575b600080fd5b6040516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020015b60405180910390f35b6100a061009b36600461044f565b6100ec565b005b6100cb6100b0366004610479565b6001600160a01b031660009081526020819052604090205490565b604051908152602001610084565b6100a06100e736600461044f565b61029f565b6001600160a01b0382166101475760405162461bcd60e51b815260206004820152601760248201527f42616e6b3a20696e76616c696420726563697069656e7400000000000000000060448201526064015b60405180910390fd5b6001600160a01b0382166000908152602081905260408120805483929061016f90849061049b565b90915550506040516323b872dd60e01b8152336004820152306024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303816000875af11580156101e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020b91906104c1565b6102575760405162461bcd60e51b815260206004820152601960248201527f42616e6b3a207472616e7366657246726f6d206661696c656400000000000000604482015260640161013e565b60408051338152602081018390526001600160a01b038416917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62910160405180910390a25050565b33600090815260208190526040902054808211156102ff5760405162461bcd60e51b815260206004820152601860248201527f42616e6b3a206e6f7420656e6f7567682062616c616e63650000000000000000604482015260640161013e565b336000908152602081905260409081902083830390555163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015610382573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a691906104c1565b6103ea5760405162461bcd60e51b815260206004820152601560248201527410985b9ace881d1c985b9cd9995c8819985a5b1959605a1b604482015260640161013e565b604080516001600160a01b03851681526020810184905233917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a2505050565b80356001600160a01b038116811461044a57600080fd5b919050565b6000806040838503121561046257600080fd5b61046b83610433565b946020939093013593505050565b60006020828403121561048b57600080fd5b61049482610433565b9392505050565b600082198211156104bc57634e487b7160e01b600052601160045260246000fd5b500190565b6000602082840312156104d357600080fd5b8151801515811461049457600080fdfea26469706673582212202f52a7f24915f76bd55f8533504eca6464ea1199be7010f33418e3e3cb53374564736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "balanceOf(address)": { + "params": { + "_owner": "account owner" + } + }, + "depositTokens(address,uint256)": { + "details": "you may need to call `token.approve(bank, _value)`", + "params": { + "_to": "account that will have their balance increased by `_value`", + "_value": "amount of tokens to be transfered" + } + }, + "transferTokens(address,uint256)": { + "params": { + "_to": "account that will receive `_value` tokens", + "_value": "amount of tokens to be transfered" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "Deposit(address,address,uint256)": { + "notice": "`value` tokens were transfered from `from` to bankthe balance of `to` was increased by `value`" + }, + "Transfer(address,address,uint256)": { + "notice": "`value` tokens were transfered from the bank to `to`the balance of `from` was decreased by `value`" + } + }, + "kind": "user", + "methods": { + "balanceOf(address)": { + "notice": "get balance of `_owner`" + }, + "depositTokens(address,uint256)": { + "notice": "transfer `_value` tokens from caller to bankincrease the balance of `_to` by `_value`" + }, + "getToken()": { + "notice": "returns the token used internally" + }, + "transferTokens(address,uint256)": { + "notice": "transfer `_value` tokens from bank to `_to`decrease the balance of caller by `_value`" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3434, + "contract": "contracts/Bank.sol:Bank", + "label": "balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/Bitmask.json b/echo-js/deployments/localhost/Bitmask.json new file mode 100644 index 00000000..632d5fef --- /dev/null +++ b/echo-js/deployments/localhost/Bitmask.json @@ -0,0 +1,49 @@ +{ + "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "abi": [], + "transactionHash": "0xc6885a17a35d339e5d669b8beb485b75cfe164f192703a913fe371ee351eba5a", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "transactionIndex": 0, + "gasUsed": "164134", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2780cdc0c935fc9d320292c8c263afcc2ecb2ecc5ab1a156aeeba93f07a5f3f2", + "transactionHash": "0xc6885a17a35d339e5d669b8beb485b75cfe164f192703a913fe371ee351eba5a", + "logs": [], + "blockNumber": 2, + "cumulativeGasUsed": "164134", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"author\":\"Stephen Chen\",\"kind\":\"dev\",\"methods\":{},\"title\":\"Bit Mask Library\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getBit(mapping(uint256 => uint256) storage,uint256)\":{\"notice\":\"Get a bit in the bit mask\"},\"setBit(mapping(uint256 => uint256) storage,uint256,bool)\":{\"notice\":\"Set a bit in the bit mask\"}},\"notice\":\"Implements bit mask with dynamic array\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bitmask.sol\":\"Bitmask\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bitmask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\npragma solidity ^0.8.0;\\n\\n/// @title Bit Mask Library\\n/// @author Stephen Chen\\n/// @notice Implements bit mask with dynamic array\\nlibrary Bitmask {\\n /// @notice Set a bit in the bit mask\\n function setBit(\\n mapping(uint256 => uint256) storage bitmask,\\n uint256 _bit,\\n bool _value\\n ) public {\\n // calculate the number of bits has been store in bitmask now\\n uint256 positionOfMask = uint256(_bit / 256);\\n uint256 positionOfBit = _bit % 256;\\n\\n if (_value) {\\n bitmask[positionOfMask] =\\n bitmask[positionOfMask] |\\n (1 << positionOfBit);\\n } else {\\n bitmask[positionOfMask] =\\n bitmask[positionOfMask] &\\n ~(1 << positionOfBit);\\n }\\n }\\n\\n /// @notice Get a bit in the bit mask\\n function getBit(mapping(uint256 => uint256) storage bitmask, uint256 _bit)\\n public\\n view\\n returns (bool)\\n {\\n // calculate the number of bits has been store in bitmask now\\n uint256 positionOfMask = uint256(_bit / 256);\\n uint256 positionOfBit = _bit % 256;\\n\\n return ((bitmask[positionOfMask] & (1 << positionOfBit)) != 0);\\n }\\n}\\n\",\"keccak256\":\"0xe35cf68672f5844589c0e56f36aa3813ca4ffb882a55a46d15adac7e3cc889bd\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61020161003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100405760003560e01c806303fbaf73146100455780636449da101461006c575b600080fd5b610058610053366004610130565b61008e565b604051901515815260200160405180910390f35b81801561007857600080fd5b5061008c610087366004610151565b6100ce565b005b60008061009d6101008461018d565b905060006100ad610100856101a1565b6000928352602095909552506040902054600190931b909216151592915050565b60006100dc6101008461018d565b905060006100ec610100856101a1565b9050821561011057600082815260208690526040902080546001831b179055610129565b600082815260208690526040902080546001831b191690555b5050505050565b60008060408385031215610142578182fd5b50508035926020909101359150565b600080600060608486031215610165578081fd5b833592506020840135915060408401358015158114610182578182fd5b809150509250925092565b60008261019c5761019c6101b5565b500490565b6000826101b0576101b06101b5565b500690565b634e487b7160e01b600052601260045260246000fdfea26469706673582212200f8e0f4b82404ab41a0a463ebfd6ceb825dcf1eb840a650cbfc02d268876dbf464736f6c63430008040033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100405760003560e01c806303fbaf73146100455780636449da101461006c575b600080fd5b610058610053366004610130565b61008e565b604051901515815260200160405180910390f35b81801561007857600080fd5b5061008c610087366004610151565b6100ce565b005b60008061009d6101008461018d565b905060006100ad610100856101a1565b6000928352602095909552506040902054600190931b909216151592915050565b60006100dc6101008461018d565b905060006100ec610100856101a1565b9050821561011057600082815260208690526040902080546001831b179055610129565b600082815260208690526040902080546001831b191690555b5050505050565b60008060408385031215610142578182fd5b50508035926020909101359150565b600080600060608486031215610165578081fd5b833592506020840135915060408401358015158114610182578182fd5b809150509250925092565b60008261019c5761019c6101b5565b500490565b6000826101b0576101b06101b5565b500690565b634e487b7160e01b600052601260045260246000fdfea26469706673582212200f8e0f4b82404ab41a0a463ebfd6ceb825dcf1eb840a650cbfc02d268876dbf464736f6c63430008040033", + "devdoc": { + "author": "Stephen Chen", + "kind": "dev", + "methods": {}, + "title": "Bit Mask Library", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getBit(mapping(uint256 => uint256) storage,uint256)": { + "notice": "Get a bit in the bit mask" + }, + "setBit(mapping(uint256 => uint256) storage,uint256,bool)": { + "notice": "Set a bit in the bit mask" + } + }, + "notice": "Implements bit mask with dynamic array", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/BitsManipulation.json b/echo-js/deployments/localhost/BitsManipulation.json new file mode 100644 index 00000000..5b0b717e --- /dev/null +++ b/echo-js/deployments/localhost/BitsManipulation.json @@ -0,0 +1,165 @@ +{ + "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + "abi": [ + { + "inputs": [ + { + "internalType": "int32", + "name": "number", + "type": "int32" + }, + { + "internalType": "uint32", + "name": "wordSize", + "type": "uint32" + } + ], + "name": "int32SignExtension", + "outputs": [ + { + "internalType": "int32", + "name": "", + "type": "int32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "num", + "type": "uint32" + } + ], + "name": "uint32SwapEndian", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "number", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "wordSize", + "type": "uint64" + } + ], + "name": "uint64SignExtension", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "num", + "type": "uint64" + } + ], + "name": "uint64SwapEndian", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x517498de54c1c30525a68a79974070af07067770e913a9f25a8c7844df64b3a0", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + "transactionIndex": 0, + "gasUsed": "376733", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe8dedd4dd3534a61b48227e10ac64c8b8f88f27d36559141b2cc2f94621cc23c", + "transactionHash": "0x517498de54c1c30525a68a79974070af07067770e913a9f25a8c7844df64b3a0", + "logs": [], + "blockNumber": 1, + "cumulativeGasUsed": "376733", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"number\",\"type\":\"int32\"},{\"internalType\":\"uint32\",\"name\":\"wordSize\",\"type\":\"uint32\"}],\"name\":\"int32SignExtension\",\"outputs\":[{\"internalType\":\"int32\",\"name\":\"\",\"type\":\"int32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"num\",\"type\":\"uint32\"}],\"name\":\"uint32SwapEndian\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"wordSize\",\"type\":\"uint64\"}],\"name\":\"uint64SignExtension\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"num\",\"type\":\"uint64\"}],\"name\":\"uint64SwapEndian\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Felipe Argento / Stephen Chen\",\"kind\":\"dev\",\"methods\":{\"int32SignExtension(int32,uint32)\":{\"params\":{\"number\":\"signed number to be extended\",\"wordSize\":\"number of bits of the signed number, ie, 8 for int8\"}},\"uint32SwapEndian(uint32)\":{\"params\":{\"num\":\"number to have bytes swapped\"}},\"uint64SignExtension(uint64,uint64)\":{\"params\":{\"number\":\"signed number to be extended\",\"wordSize\":\"number of bits of the signed number, ie, 8 for int8\"}},\"uint64SwapEndian(uint64)\":{\"params\":{\"num\":\"number to have bytes swapped\"}}},\"title\":\"Bits Manipulation Library\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"int32SignExtension(int32,uint32)\":{\"notice\":\"Sign extend a shorter signed value to the full int32\"},\"uint32SwapEndian(uint32)\":{\"notice\":\"Swap byte order of unsigned ints with 32 bytes\"},\"uint64SignExtension(uint64,uint64)\":{\"notice\":\"Sign extend a shorter signed value to the full uint64\"},\"uint64SwapEndian(uint64)\":{\"notice\":\"Swap byte order of unsigned ints with 64 bytes\"}},\"notice\":\"Implements bit manipulation helper functions\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BitsManipulation.sol\":\"BitsManipulation\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/BitsManipulation.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\npragma solidity ^0.8.0;\\n\\n/// @title Bits Manipulation Library\\n/// @author Felipe Argento / Stephen Chen\\n/// @notice Implements bit manipulation helper functions\\nlibrary BitsManipulation {\\n\\n /// @notice Sign extend a shorter signed value to the full int32\\n /// @param number signed number to be extended\\n /// @param wordSize number of bits of the signed number, ie, 8 for int8\\n function int32SignExtension(int32 number, uint32 wordSize)\\n public pure returns(int32)\\n {\\n uint32 uNumber = uint32(number);\\n bool isNegative = ((uint64(1) << (wordSize - 1)) & uNumber) > 0;\\n uint32 mask = ((uint32(2) ** wordSize) - 1);\\n\\n if (isNegative) {\\n uNumber = uNumber | ~mask;\\n }\\n\\n return int32(uNumber);\\n }\\n\\n /// @notice Sign extend a shorter signed value to the full uint64\\n /// @param number signed number to be extended\\n /// @param wordSize number of bits of the signed number, ie, 8 for int8\\n function uint64SignExtension(uint64 number, uint64 wordSize)\\n public pure returns(uint64)\\n {\\n uint64 uNumber = number;\\n bool isNegative = ((uint64(1) << (wordSize - 1)) & uNumber) > 0;\\n uint64 mask = ((uint64(2) ** wordSize) - 1);\\n\\n if (isNegative) {\\n uNumber = uNumber | ~mask;\\n }\\n\\n return uNumber;\\n }\\n\\n /// @notice Swap byte order of unsigned ints with 64 bytes\\n /// @param num number to have bytes swapped\\n function uint64SwapEndian(uint64 num) public pure returns(uint64) {\\n uint64 output = ((num & 0x00000000000000ff) << 56)|\\n ((num & 0x000000000000ff00) << 40)|\\n ((num & 0x0000000000ff0000) << 24)|\\n ((num & 0x00000000ff000000) << 8) |\\n ((num & 0x000000ff00000000) >> 8) |\\n ((num & 0x0000ff0000000000) >> 24)|\\n ((num & 0x00ff000000000000) >> 40)|\\n ((num & 0xff00000000000000) >> 56);\\n\\n return output;\\n }\\n\\n /// @notice Swap byte order of unsigned ints with 32 bytes\\n /// @param num number to have bytes swapped\\n function uint32SwapEndian(uint32 num) public pure returns(uint32) {\\n uint32 output = ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | ((num >> 8) & 0xff00) | ((num << 24) & 0xff000000);\\n return output;\\n }\\n}\\n\\n\",\"keccak256\":\"0x09e8d9397126dfc40a92d4099060c1615a4fbd99edd12afea5e5163ec8ce8aba\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6105da61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c8063240034ec1461005b578063bf1924c5146100b0578063ef7c79491461014d578063f69c389b14610160575b600080fd5b6100966100693660046102ab565b601881811b63ff00000016600883811c61ff00169084901b62ff0000169390921c60ff1692909217171790565b60405163ffffffff90911681526020015b60405180910390f35b6101356100be3660046102cc565b603881811b67ff0000000000000016602883811b66ff0000000000001691909117601884811b65ff00000000001691909117600885811b64ff00000000169190911763ff0000009186901c919091161762ff00009185901c919091161761ff009184901c919091161760ff9290911c919091161790565b6040516001600160401b0390911681526020016100a7565b61013561015b3660046102e6565b610186565b61017361016e366004610272565b6101f0565b60405160039190910b81526020016100a7565b600082818082610197600187610572565b6001600160401b031660016001600160401b0316901b166001600160401b0316119050600060018560026101cb91906103b1565b6101d59190610572565b905081156101e4578019831792505b50909150505b92915050565b600082818063ffffffff831661020760018761054d565b63ffffffff1660016001600160401b0316901b166001600160401b0316119050600060018560026102389190610394565b6101d5919061054d565b803563ffffffff8116811461025657600080fd5b919050565b80356001600160401b038116811461025657600080fd5b60008060408385031215610284578182fd5b82358060030b8114610294578283fd5b91506102a260208401610242565b90509250929050565b6000602082840312156102bc578081fd5b6102c582610242565b9392505050565b6000602082840312156102dd578081fd5b6102c58261025b565b600080604083850312156102f8578182fd5b6103018361025b565b91506102a26020840161025b565b600181815b8085111561034c578163ffffffff048211156103325761033261058e565b8085161561033f57918102915b93841c9390800290610314565b509250929050565b600181815b8085111561034c57816001600160401b030482111561037a5761037a61058e565b8085161561038757918102915b93841c9390800290610359565b600063ffffffff6103a98185168285166103c9565b949350505050565b60006001600160401b036103a9818516828516610495565b6000826103d8575060016101ea565b816103e5575060006101ea565b81600181146103fb576002811461040557610436565b60019150506101ea565b60ff8411156104165761041661058e565b6001841b915063ffffffff8211156104305761043061058e565b506101ea565b5060208310610133831016604e8410600b841016171561046d575081810a63ffffffff8111156104685761046861058e565b6101ea565b610477838361030f565b8063ffffffff0482111561048d5761048d61058e565b029392505050565b6000826104a4575060016101ea565b816104b1575060006101ea565b81600181146103fb57600281146104c7576104f5565b60ff8411156104d8576104d861058e565b6001841b91506001600160401b038211156104305761043061058e565b5060208310610133831016604e8410600b841016171561052a575081810a6001600160401b038111156104685761046861058e565b6105348383610354565b806001600160401b030482111561048d5761048d61058e565b600063ffffffff8381169083168181101561056a5761056a61058e565b039392505050565b60006001600160401b038381169083168181101561056a5761056a5b634e487b7160e01b600052601160045260246000fdfea2646970667358221220d1a282b405bea3ac1b1041d4f9042915951dc97e60ea81d0a585311c188e81e664736f6c63430008040033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c8063240034ec1461005b578063bf1924c5146100b0578063ef7c79491461014d578063f69c389b14610160575b600080fd5b6100966100693660046102ab565b601881811b63ff00000016600883811c61ff00169084901b62ff0000169390921c60ff1692909217171790565b60405163ffffffff90911681526020015b60405180910390f35b6101356100be3660046102cc565b603881811b67ff0000000000000016602883811b66ff0000000000001691909117601884811b65ff00000000001691909117600885811b64ff00000000169190911763ff0000009186901c919091161762ff00009185901c919091161761ff009184901c919091161760ff9290911c919091161790565b6040516001600160401b0390911681526020016100a7565b61013561015b3660046102e6565b610186565b61017361016e366004610272565b6101f0565b60405160039190910b81526020016100a7565b600082818082610197600187610572565b6001600160401b031660016001600160401b0316901b166001600160401b0316119050600060018560026101cb91906103b1565b6101d59190610572565b905081156101e4578019831792505b50909150505b92915050565b600082818063ffffffff831661020760018761054d565b63ffffffff1660016001600160401b0316901b166001600160401b0316119050600060018560026102389190610394565b6101d5919061054d565b803563ffffffff8116811461025657600080fd5b919050565b80356001600160401b038116811461025657600080fd5b60008060408385031215610284578182fd5b82358060030b8114610294578283fd5b91506102a260208401610242565b90509250929050565b6000602082840312156102bc578081fd5b6102c582610242565b9392505050565b6000602082840312156102dd578081fd5b6102c58261025b565b600080604083850312156102f8578182fd5b6103018361025b565b91506102a26020840161025b565b600181815b8085111561034c578163ffffffff048211156103325761033261058e565b8085161561033f57918102915b93841c9390800290610314565b509250929050565b600181815b8085111561034c57816001600160401b030482111561037a5761037a61058e565b8085161561038757918102915b93841c9390800290610359565b600063ffffffff6103a98185168285166103c9565b949350505050565b60006001600160401b036103a9818516828516610495565b6000826103d8575060016101ea565b816103e5575060006101ea565b81600181146103fb576002811461040557610436565b60019150506101ea565b60ff8411156104165761041661058e565b6001841b915063ffffffff8211156104305761043061058e565b506101ea565b5060208310610133831016604e8410600b841016171561046d575081810a63ffffffff8111156104685761046861058e565b6101ea565b610477838361030f565b8063ffffffff0482111561048d5761048d61058e565b029392505050565b6000826104a4575060016101ea565b816104b1575060006101ea565b81600181146103fb57600281146104c7576104f5565b60ff8411156104d8576104d861058e565b6001841b91506001600160401b038211156104305761043061058e565b5060208310610133831016604e8410600b841016171561052a575081810a6001600160401b038111156104685761046861058e565b6105348383610354565b806001600160401b030482111561048d5761048d61058e565b600063ffffffff8381169083168181101561056a5761056a61058e565b039392505050565b60006001600160401b038381169083168181101561056a5761056a5b634e487b7160e01b600052601160045260246000fdfea2646970667358221220d1a282b405bea3ac1b1041d4f9042915951dc97e60ea81d0a585311c188e81e664736f6c63430008040033", + "devdoc": { + "author": "Felipe Argento / Stephen Chen", + "kind": "dev", + "methods": { + "int32SignExtension(int32,uint32)": { + "params": { + "number": "signed number to be extended", + "wordSize": "number of bits of the signed number, ie, 8 for int8" + } + }, + "uint32SwapEndian(uint32)": { + "params": { + "num": "number to have bytes swapped" + } + }, + "uint64SignExtension(uint64,uint64)": { + "params": { + "number": "signed number to be extended", + "wordSize": "number of bits of the signed number, ie, 8 for int8" + } + }, + "uint64SwapEndian(uint64)": { + "params": { + "num": "number to have bytes swapped" + } + } + }, + "title": "Bits Manipulation Library", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "int32SignExtension(int32,uint32)": { + "notice": "Sign extend a shorter signed value to the full int32" + }, + "uint32SwapEndian(uint32)": { + "notice": "Swap byte order of unsigned ints with 32 bytes" + }, + "uint64SignExtension(uint64,uint64)": { + "notice": "Sign extend a shorter signed value to the full uint64" + }, + "uint64SwapEndian(uint64)": { + "notice": "Swap byte order of unsigned ints with 64 bytes" + } + }, + "notice": "Implements bit manipulation helper functions", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/CartesiDAppFactory.json b/echo-js/deployments/localhost/CartesiDAppFactory.json new file mode 100644 index 00000000..0a4c3c63 --- /dev/null +++ b/echo-js/deployments/localhost/CartesiDAppFactory.json @@ -0,0 +1,477 @@ +{ + "address": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IDiamondCut", + "name": "diamondCutFacet", + "type": "address" + }, + { + "internalType": "contract DiamondInit", + "name": "diamondInit", + "type": "address" + }, + { + "internalType": "contract IBank", + "name": "feeManagerBank", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "internalType": "struct CartesiDAppFactory.FactoryConfig", + "name": "_fConfig", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CartesiDApp", + "name": "application", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "diamondOwner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "templateHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "inputDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputLog2Size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feePerClaim", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeManagerOwner", + "type": "address" + }, + { + "internalType": "address payable[]", + "name": "validators", + "type": "address[]" + } + ], + "indexed": false, + "internalType": "struct ICartesiDAppFactory.AppConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "ApplicationCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "diamondCut", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "diamondCutFacet", + "outputs": [ + { + "internalType": "contract IDiamondCut", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "diamondInit", + "outputs": [ + { + "internalType": "contract DiamondInit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManagerBank", + "outputs": [ + { + "internalType": "contract IBank", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "diamondOwner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "templateHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "inputDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputLog2Size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feePerClaim", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeManagerOwner", + "type": "address" + }, + { + "internalType": "address payable[]", + "name": "validators", + "type": "address[]" + } + ], + "internalType": "struct ICartesiDAppFactory.AppConfig", + "name": "_appConfig", + "type": "tuple" + } + ], + "name": "newApplication", + "outputs": [ + { + "internalType": "contract CartesiDApp", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x4d734e09fce02f10d7448da1d1c8e1f314baa9ab05cb559c3ce8dc9b5b06c075", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690", + "transactionIndex": 0, + "gasUsed": "3301783", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa6cf4b826a9506cdd281c119dcde42a2b2733e1d017ed11af9259484f7908169", + "transactionHash": "0x4d734e09fce02f10d7448da1d1c8e1f314baa9ab05cb559c3ce8dc9b5b06c075", + "logs": [], + "blockNumber": 32, + "cumulativeGasUsed": "3301783", + "status": 1, + "byzantium": true + }, + "args": [ + { + "diamondCutFacet": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "diamondInit": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", + "feeManagerBank": "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E", + "diamondCut": [ + { + "facetAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", + "action": 0, + "functionSelectors": [ + "0xcdffacc6", + "0x52ef6b2c", + "0xadfca15e", + "0x7a0ed627", + "0x01ffc9a7" + ] + }, + { + "facetAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "action": 0, + "functionSelectors": [ + "0x8da5cb5b", + "0xf2fde38b" + ] + }, + { + "facetAddress": "0x59b670e9fA9D0A427751Af201D676719a970857b", + "action": 0, + "functionSelectors": [ + "0xcb1061a6" + ] + }, + { + "facetAddress": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1", + "action": 0, + "functionSelectors": [ + "0x15e55ce5", + "0x150b7a02" + ] + }, + { + "facetAddress": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44", + "action": 0, + "functionSelectors": [ + "0x2abfe7b3", + "0x74956b94" + ] + }, + { + "facetAddress": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f", + "action": 0, + "functionSelectors": [ + "0x6e964cea", + "0xa859b983", + "0xe8f56171", + "0xde7a8d11", + "0x7a5bf67c" + ] + }, + { + "facetAddress": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319", + "action": 0, + "functionSelectors": [ + "0xf32078e8", + "0x1ab6dcab", + "0xa459600e", + "0xe7955244" + ] + }, + { + "facetAddress": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", + "action": 0, + "functionSelectors": [ + "0x6190d81e", + "0x3c0d9958", + "0xa2382036", + "0xf3af7efd", + "0x10517cfc", + "0x8021be81", + "0x83552b4d", + "0xa981588a", + "0x3ad58a27", + "0x5e439a0c" + ] + }, + { + "facetAddress": "0x09635F643e140090A9A8Dcd712eD6285858ceBef", + "action": 0, + "functionSelectors": [ + "0xbd66528a", + "0x82ae9ef7", + "0x7864b77d", + "0xb97dd9e2", + "0xa3a40ea5", + "0xddf7bcf0", + "0xe17ba012", + "0x54ee1da5", + "0x61b12c66" + ] + }, + { + "facetAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "action": 0, + "functionSelectors": [ + "0x101494ce", + "0xf6023815", + "0x8219fda4", + "0xd2992f54", + "0x55564a70", + "0xcc8a2451", + "0x1fcc449e" + ] + } + ] + } + ], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"contract IDiamondCut\",\"name\":\"diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"contract DiamondInit\",\"name\":\"diamondInit\",\"type\":\"address\"},{\"internalType\":\"contract IBank\",\"name\":\"feeManagerBank\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"internalType\":\"struct CartesiDAppFactory.FactoryConfig\",\"name\":\"_fConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract CartesiDApp\",\"name\":\"application\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"diamondOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"templateHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"inputDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"challengePeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inputLog2Size\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePerClaim\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"feeManagerOwner\",\"type\":\"address\"},{\"internalType\":\"address payable[]\",\"name\":\"validators\",\"type\":\"address[]\"}],\"indexed\":false,\"internalType\":\"struct ICartesiDAppFactory.AppConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ApplicationCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"diamondCut\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"diamondCutFacet\",\"outputs\":[{\"internalType\":\"contract IDiamondCut\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"diamondInit\",\"outputs\":[{\"internalType\":\"contract DiamondInit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeManagerBank\",\"outputs\":[{\"internalType\":\"contract IBank\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"diamondOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"templateHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"inputDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"challengePeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inputLog2Size\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePerClaim\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"feeManagerOwner\",\"type\":\"address\"},{\"internalType\":\"address payable[]\",\"name\":\"validators\",\"type\":\"address[]\"}],\"internalType\":\"struct ICartesiDAppFactory.AppConfig\",\"name\":\"_appConfig\",\"type\":\"tuple\"}],\"name\":\"newApplication\",\"outputs\":[{\"internalType\":\"contract CartesiDApp\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"newApplication((address,bytes32,uint256,uint256,uint256,uint256,address,address[]))\":{\"params\":{\"_appConfig\":\"application configurations\"},\"returns\":{\"_0\":\"application address\"}}},\"version\":1},\"userdoc\":{\"events\":{\"ApplicationCreated(address,(address,bytes32,uint256,uint256,uint256,uint256,address,address[]))\":{\"notice\":\"Event emitted when a new application is deployed\"}},\"kind\":\"user\",\"methods\":{\"newApplication((address,bytes32,uint256,uint256,uint256,uint256,address,address[]))\":{\"notice\":\"Deploy a new application\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/CartesiDAppFactory.sol\":\"CartesiDAppFactory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/CartesiDApp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\ncontract CartesiDApp {\\n constructor(address _contractOwner, address _diamondCutFacet) payable {\\n LibDiamond.setContractOwner(_contractOwner);\\n\\n // Add the diamondCut external function from the diamondCutFacet\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n // Find facet for function that is called and execute the\\n // function if a facet is found and return any value.\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n require(facet != address(0), \\\"Diamond: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0x5dcf7607e87afc097540bc36b53f4bf6cf5e037027441218ec5d78362fa7f3b7\",\"license\":\"MIT\"},\"contracts/CartesiDAppFactory.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Cartesi DApp Factory\\npragma solidity ^0.8.0;\\n\\nimport {ICartesiDAppFactory} from \\\"./ICartesiDAppFactory.sol\\\";\\nimport {CartesiDApp} from \\\"./CartesiDApp.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\nimport {IERC173} from \\\"./interfaces/IERC173.sol\\\";\\nimport {DiamondInit, DiamondConfig} from \\\"./upgrade_initializers/DiamondInit.sol\\\";\\nimport {IBank} from \\\"./IBank.sol\\\";\\n\\ncontract CartesiDAppFactory is ICartesiDAppFactory {\\n IDiamondCut public immutable diamondCutFacet;\\n DiamondInit public immutable diamondInit;\\n IBank public immutable feeManagerBank;\\n IDiamondCut.FacetCut[] public diamondCut;\\n\\n struct FactoryConfig {\\n IDiamondCut diamondCutFacet;\\n DiamondInit diamondInit;\\n IBank feeManagerBank;\\n IDiamondCut.FacetCut[] diamondCut;\\n }\\n\\n constructor(FactoryConfig memory _fConfig) {\\n diamondCutFacet = _fConfig.diamondCutFacet;\\n diamondInit = _fConfig.diamondInit;\\n feeManagerBank = _fConfig.feeManagerBank;\\n for (uint256 i; i < _fConfig.diamondCut.length; ++i) {\\n diamondCut.push(_fConfig.diamondCut[i]);\\n }\\n }\\n\\n function newApplication(AppConfig calldata _appConfig)\\n public\\n returns (CartesiDApp)\\n {\\n CartesiDApp application = new CartesiDApp(\\n address(this),\\n address(diamondCutFacet)\\n );\\n DiamondConfig memory dConfig = DiamondConfig({\\n templateHash: _appConfig.templateHash,\\n inputDuration: _appConfig.inputDuration,\\n challengePeriod: _appConfig.challengePeriod,\\n inputLog2Size: _appConfig.inputLog2Size,\\n feePerClaim: _appConfig.feePerClaim,\\n feeManagerBank: address(feeManagerBank),\\n feeManagerOwner: _appConfig.feeManagerOwner,\\n validators: _appConfig.validators\\n });\\n IDiamondCut(address(application)).diamondCut(\\n diamondCut,\\n address(diamondInit),\\n abi.encodeWithSelector(DiamondInit.init.selector, dConfig)\\n );\\n IERC173(address(application)).transferOwnership(\\n _appConfig.diamondOwner\\n );\\n emit ApplicationCreated(application, _appConfig);\\n return application;\\n }\\n}\\n\",\"keccak256\":\"0x5b457605c89dfaa9dcbb49d49c0fa5de6cddd16ad53459ffddb2137bb843fc08\",\"license\":\"Apache-2.0\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/ICartesiDAppFactory.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Cartesi DApp Factory interface\\npragma solidity ^0.8.0;\\n\\nimport {CartesiDApp} from \\\"./CartesiDApp.sol\\\";\\n\\ninterface ICartesiDAppFactory {\\n /// @notice application configurations\\n /// @param diamondOwner diamond owner\\n /// @param templateHash state hash of the cartesi machine at t0\\n /// @param inputDuration duration of input accumulation phase in seconds\\n /// @param challengePeriod duration of challenge period in seconds\\n /// @param inputLog2Size size of the input memory range in this machine\\n /// @param feePerClaim fee per claim to reward the validators\\n /// @param feeManagerOwner fee manager owner address\\n /// @param validators initial validator set\\n /// @dev validators have to be unique, if the same validator is added twice\\n /// consensus will never be reached\\n struct AppConfig {\\n // DiamondCutFacet\\n address diamondOwner;\\n // RollupsFacet\\n bytes32 templateHash;\\n uint256 inputDuration;\\n uint256 challengePeriod;\\n // InputFacet\\n uint256 inputLog2Size;\\n // FeeManagerFacet\\n uint256 feePerClaim;\\n address feeManagerOwner;\\n // ValidatorManagerFacet\\n address payable[] validators;\\n }\\n\\n /// @notice Deploy a new application\\n /// @param _appConfig application configurations\\n /// @return application address\\n function newApplication(AppConfig calldata _appConfig)\\n external\\n returns (CartesiDApp);\\n\\n /// @notice Event emitted when a new application is deployed\\n /// @param application application address\\n /// @param config application configurations\\n event ApplicationCreated(CartesiDApp indexed application, AppConfig config);\\n}\\n\",\"keccak256\":\"0x2aab51e8e50a25183ff902a19680e2e47602624a631fbcdd1f61259adbb60609\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\\n}\\n\",\"keccak256\":\"0x6a3129be1f39b6fec871f2c94bf7debf2d6a4e665547a4d83e7f2def38359e44\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet)\\n external\\n view\\n returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector)\\n external\\n view\\n returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd6c3796a7c45baea6e47fdd5f2cec95d7796991bc9a949604f99875590962a67\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0xc47289cda9c9cdb749612eb82ccb9abf9ab08dca74bdca22292ae7f765a15a5f\",\"license\":\"MIT\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] diamondCut,\\n address init,\\n bytes callData\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x740ea3845282f09bb822e66a189ed431ac799ab08184de7457ef53799b2e99d6\",\"license\":\"MIT\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"},\"contracts/upgrade_initializers/DiamondInit.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Diamond Initialization Contract\\npragma solidity ^0.8.0;\\n\\n// Rollups-related dependencies\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\n// Diamond-related dependencies\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {IDiamondLoupe} from \\\"../interfaces/IDiamondLoupe.sol\\\";\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\nimport {IERC173} from \\\"../interfaces/IERC173.sol\\\"; // not in openzeppelin-contracts yet\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\n/// @notice diamond configurations\\n/// @param templateHash state hash of the cartesi machine at t0\\n/// @param inputDuration duration of input accumulation phase in seconds\\n/// @param challengePeriod duration of challenge period in seconds\\n/// @param inputLog2Size size of the input memory range in this machine\\n/// @param feePerClaim fee per claim to reward the validators\\n/// @param feeManagerBank fee manager bank address\\n/// @param feeManagerOwner fee manager owner address\\n/// @param validators initial validator set\\n/// @dev validators have to be unique, if the same validator is added twice\\n/// consensus will never be reached\\nstruct DiamondConfig {\\n // RollupsFacet\\n bytes32 templateHash;\\n uint256 inputDuration;\\n uint256 challengePeriod;\\n // InputFacet\\n uint256 inputLog2Size;\\n // FeeManagerFacet\\n uint256 feePerClaim;\\n address feeManagerBank;\\n address feeManagerOwner;\\n // ValidatorManagerFacet\\n address payable[] validators;\\n}\\n\\ncontract DiamondInit {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibInput for LibInput.DiamondStorage;\\n\\n /// @notice initialize the diamond\\n /// @param _dConfig diamond configurations\\n function init(DiamondConfig calldata _dConfig) external {\\n initERC165();\\n initValidatorManager(_dConfig.validators);\\n initRollups(\\n _dConfig.templateHash,\\n _dConfig.inputDuration,\\n _dConfig.challengePeriod\\n );\\n initFeeManager(\\n _dConfig.feePerClaim,\\n _dConfig.feeManagerBank,\\n _dConfig.feeManagerOwner\\n );\\n initInput(_dConfig.inputLog2Size);\\n }\\n\\n /// @notice initialize ERC165 data\\n function initERC165() private {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n ds.supportedInterfaces[type(IERC165).interfaceId] = true;\\n ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;\\n ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;\\n ds.supportedInterfaces[type(IERC173).interfaceId] = true;\\n }\\n\\n /// @notice initalize the Input facet\\n /// @param _inputLog2Size size of the input memory range in this machine\\n function initInput(uint256 _inputLog2Size) private {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n\\n require(\\n _inputLog2Size >= 3 && _inputLog2Size <= 64,\\n \\\"Log of input size: [3,64]\\\"\\n );\\n\\n inputDS.inputDriveSize = (1 << _inputLog2Size);\\n\\n // input box gets initialized with one empty input\\n // so that the L2 DApp knows it's own address\\n inputDS.addInternalInput(\\\"\\\");\\n }\\n\\n /// @notice initialize the Validator Manager facet\\n /// @param _validators initial validator set\\n function initValidatorManager(address payable[] memory _validators)\\n private\\n {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n uint256 maxNumValidators = _validators.length;\\n\\n require(maxNumValidators <= 8, \\\"up to 8 validators\\\");\\n\\n validatorManagerDS.validators = _validators;\\n validatorManagerDS.maxNumValidators = maxNumValidators;\\n\\n // create a new ClaimsMask, with only the consensus goal set,\\n // according to the number of validators\\n validatorManagerDS.claimsMask = LibClaimsMask\\n .newClaimsMaskWithConsensusGoalSet(maxNumValidators);\\n }\\n\\n /// @notice rollups contract initialized\\n /// @param inputDuration duration of input accumulation phase in seconds\\n /// @param challengePeriod duration of challenge period in seconds\\n event RollupsInitialized(uint256 inputDuration, uint256 challengePeriod);\\n\\n /// @notice initialize the Rollups facet\\n /// @param _templateHash state hash of the cartesi machine at t0\\n /// @param _inputDuration duration of input accumulation phase in seconds\\n /// @param _challengePeriod duration of challenge period in seconds\\n function initRollups(\\n bytes32 _templateHash,\\n uint256 _inputDuration,\\n uint256 _challengePeriod\\n ) private {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n rollupsDS.templateHash = _templateHash;\\n rollupsDS.inputDuration = uint32(_inputDuration);\\n rollupsDS.challengePeriod = uint32(_challengePeriod);\\n rollupsDS.inputAccumulationStart = uint32(block.timestamp);\\n rollupsDS.currentPhase_int = uint32(Phase.InputAccumulation);\\n\\n emit RollupsInitialized(_inputDuration, _challengePeriod);\\n }\\n\\n /// @notice FeeManagerImpl contract initialized\\n /// @param feePerClaim fee per claim to reward the validators\\n /// @param feeManagerBank fee manager bank address\\n /// @param feeManagerOwner fee manager owner address\\n event FeeManagerInitialized(\\n uint256 feePerClaim,\\n address feeManagerBank,\\n address feeManagerOwner\\n );\\n\\n /// @notice initalize the Fee Manager facet\\n /// @param _feePerClaim fee per claim to reward the validators\\n /// @param _feeManagerBank fee manager bank address\\n /// @param _feeManagerOwner fee manager owner address\\n function initFeeManager(\\n uint256 _feePerClaim,\\n address _feeManagerBank,\\n address _feeManagerOwner\\n ) private {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n\\n feeManagerDS.feePerClaim = _feePerClaim;\\n feeManagerDS.bank = IBank(_feeManagerBank);\\n feeManagerDS.owner = _feeManagerOwner;\\n\\n emit FeeManagerInitialized(\\n _feePerClaim,\\n _feeManagerBank,\\n _feeManagerOwner\\n );\\n }\\n}\\n\",\"keccak256\":\"0xe627b754df9ee7265f1031cc946bb27d1de8dbb29a7e745453682420b5d9ee76\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60e06040523480156200001157600080fd5b5060405162003159380380620031598339810160408190526200003491620002d9565b80516001600160a01b039081166080526020820151811660a05260408201511660c05260005b8160600151518110156200012f57600082606001518281518110620000835762000083620004e0565b60209081029190910181015182546001810184556000938452928290208151600294850290910180546001600160a01b039092166001600160a01b0319831681178255938301519294909384926001600160a81b0319161790600160a01b908490811115620000f657620000f6620004f6565b0217905550604082015180516200011891600184019160209091019062000137565b5050508062000127906200050c565b90506200005a565b505062000534565b82805482825590600052602060002090600701600890048101928215620001d85791602002820160005b83821115620001a457835183826101000a81548163ffffffff021916908360e01c0217905550926020019260040160208160030104928301926001030262000161565b8015620001d65782816101000a81549063ffffffff0219169055600401602081600301049283019260010302620001a4565b505b50620001e6929150620001ea565b5090565b5b80821115620001e65760008155600101620001eb565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200023c576200023c62000201565b60405290565b604051606081016001600160401b03811182821017156200023c576200023c62000201565b604051601f8201601f191681016001600160401b038111828210171562000292576200029262000201565b604052919050565b6001600160a01b0381168114620002b057600080fd5b50565b60006001600160401b03821115620002cf57620002cf62000201565b5060051b60200190565b60006020808385031215620002ed57600080fd5b82516001600160401b03808211156200030557600080fd5b90840190608082870312156200031a57600080fd5b6200032462000217565b825162000331816200029a565b81528284015162000342816200029a565b81850152604083015162000356816200029a565b60408201526060830151828111156200036e57600080fd5b80840193505086601f8401126200038457600080fd5b82516200039b6200039582620002b3565b62000267565b81815260059190911b84018501908581019089831115620003bb57600080fd5b8686015b83811015620004cd57805186811115620003d857600080fd5b87016060818d03601f19011215620003ef57600080fd5b620003f962000242565b8982015162000408816200029a565b81526040820151600381106200041d57600080fd5b818b01526060820151888111156200043457600080fd5b8083019250508c603f8301126200044a57600080fd5b898201516200045d6200039582620002b3565b81815260059190911b8301604001908b8101908f8311156200047e57600080fd5b6040850194505b82851015620004b75784516001600160e01b031981168114620004a757600080fd5b8252938c0193908c019062000485565b60408401525050845250918701918701620003bf565b5060608401525090979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6000600182016200052d57634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c051612be2620005776000396000818160f1015261022201526000818161011901526102ce01526000818160c9015261017c0152612be26000f3fe60806040523480156200001157600080fd5b50600436106200005e5760003560e01c806304c01cc7146200006357806394a28f321462000093578063a051e9b314620000c3578063aa9a6e9114620000eb578063e6ee1d4f1462000113575b600080fd5b6200007a6200007436600462000456565b6200013b565b6040516200008a92919062000493565b60405180910390f35b620000aa620000a4366004620004b9565b62000176565b6040516001600160a01b0390911681526020016200008a565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b600081815481106200014c57600080fd5b60009182526020909120600290910201546001600160a01b0381169150600160a01b900460ff1682565b600080307f0000000000000000000000000000000000000000000000000000000000000000604051620001a99062000448565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620001dd573d6000803e3d6000fd5b5090506000604051806101000160405280856020013581526020018560400135815260200185606001358152602001856080013581526020018560a0013581526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018560c001602081019062000264919062000523565b6001600160a01b031681526020016200028160e087018762000543565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509390945250506040519293506001600160a01b03851692631f931c1c92507f00000000000000000000000000000000000000000000000000000000000000009063af52770160e01b9062000307908790602401620005dd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e086901b909216825262000350939291600401620006b8565b600060405180830381600087803b1580156200036b57600080fd5b505af115801562000380573d6000803e3d6000fd5b5050506001600160a01b038316905063f2fde38b620003a3602087018762000523565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620003e557600080fd5b505af1158015620003fa573d6000803e3d6000fd5b50505050816001600160a01b03167f43883daeb0f23afe0fbb9658d1d4c08379520e9654a30f7ea3a9fb3a8f5195bb8560405162000439919062000a2b565b60405180910390a25092915050565b6120df8062000ace83390190565b6000602082840312156200046957600080fd5b5035919050565b600381106200048f57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b038316815260408101620004b2602083018462000470565b9392505050565b600060208284031215620004cc57600080fd5b813567ffffffffffffffff811115620004e457600080fd5b82016101008185031215620004b257600080fd5b6001600160a01b03811681146200050e57600080fd5b50565b80356200051e81620004f8565b919050565b6000602082840312156200053657600080fd5b8135620004b281620004f8565b6000808335601e198436030181126200055b57600080fd5b83018035915067ffffffffffffffff8211156200057757600080fd5b6020019150600581901b36038213156200059057600080fd5b9250929050565b600081518084526020808501945080840160005b83811015620005d25781516001600160a01b031687529582019590820190600101620005ab565b509495945050505050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a083015160018060a01b0380821660c08501528060c08601511660e0850152505060e08301516101008081850152506200065261012084018262000597565b949350505050565b6001600160e01b0319169052565b6000815180845260005b81811015620006905760208185018101518683018201520162000672565b81811115620006a3576000602083870101525b50601f01601f19169290920160200192915050565b60608152600060608201855480825260808401915060808160051b8501018760005260208060002060005b848110156200096d57878403607f1901865281546001600160a01b038116855260608501906200071d85870160a083901c60ff1662000470565b506060604086015260018381018054808452600091825260208083209401905b80600784011015620008055784546200075a838260e01b6200065a565b6001600160e01b031962000777848b0160c084901b83166200065a565b6200078b60408501828460a01b166200065a565b6200079f60608501828460801b166200065a565b620007b360808501828460601b166200065a565b620007c760a08501828460401b166200065a565b620007da60c0850182848d1b166200065a565b620007eb60e085018284166200065a565b50506101008201915083850194506008830192506200073d565b93549380831015620008295762000820828660e01b6200065a565b91830191908701905b8083101562000855576200084c8260c087901b6001600160e01b0319166200065a565b91830191908701905b808310156200088157620008788260a087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008ad57620008a482608087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008d957620008d082606087901b6001600160e01b0319166200065a565b91830191908701905b808310156200090557620008fc82604087901b6001600160e01b0319166200065a565b91830191908701905b808310156200092f576200092682868a1b6001600160e01b0319166200065a565b91830191908701905b8083101562000953576200094e826001600160e01b031987166200065a565b908701905b5098860198965050506002929092019150600101620006e3565b50506001600160a01b03881690860152848103604086015262000991818762000668565b98975050505050505050565b6000808335601e19843603018112620009b557600080fd5b830160208101925035905067ffffffffffffffff811115620009d657600080fd5b8060051b36038313156200059057600080fd5b8183526000602080850194508260005b85811015620005d257813562000a0f81620004f8565b6001600160a01b031687529582019590820190600101620009f9565b602081526000823562000a3e81620004f8565b60018060a01b038116602084015250602083013560408301526040830135606083015260608301356080830152608083013560a083015260a083013560c083015262000a8d60c0840162000511565b6001600160a01b03811660e08401525062000aac60e08401846200099d565b6101008481015262000ac461012085018284620009e9565b9594505050505056fe6080604052604051620020df380380620020df833981016040819052620000269162000ddc565b6200003c826200015660201b620000b01760201c565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620000535750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000c657620000c662000e14565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038516815290810160008152602001828152508260008151811062000119576200011962000e14565b60200260200101819052506200014c82600060405180602001604052806000815250620001da60201b620001331760201c565b5050505062001067565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040516000805160206200204b833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546000805160206200204b8339815191529061ffff811690819060009060071615620002395750600381901c60009081526001840160205260409020545b60005b8751811015620002d557620002bb83838a848151811062000261576200026162000e14565b6020026020010151600001518b858151811062000282576200028262000e14565b6020026020010151602001518c8681518110620002a357620002a362000e14565b6020026020010151604001516200036760201b60201c565b909350915080620002cc8162000e56565b9150506200023c565b50828214620002f25760028401805461ffff191661ffff84161790555b60078216156200031557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200034a9392919062000ecf565b60405180910390a16200035e868662000b76565b50505050505050565b600080806000805160206200204b83398151915290506000845111620003e85760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084015b60405180910390fd5b6000856002811115620003ff57620003ff62000e2a565b0362000585576200042a866040518060600160405280602481526020016200206b6024913962000d9b565b60005b84518110156200057e5760008582815181106200044e576200044e62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c15620004f15760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620003df565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a819003620005565760038c901c600090815260018601602052604081209b909b555b8b620005628162000e56565b9c50505050508080620005759062000e56565b9150506200042d565b5062000b6a565b60018560028111156200059c576200059c62000e2a565b03620007b557620005c786604051806060016040528060288152602001620020b76028913962000d9b565b60005b84518110156200057e576000858281518110620005eb57620005eb62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c308103620006825760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401620003df565b896001600160a01b0316816001600160a01b031603620006fa5760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401620003df565b6001600160a01b038116620007675760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401620003df565b506001600160e01b031990911660009081526020849052604090206001600160601b03919091166001600160601b031960608a901b1617905580620007ac8162000e56565b915050620005ca565b6002856002811115620007cc57620007cc62000e2a565b0362000b11576001600160a01b03861615620008515760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620003df565b600388901c6007891660005b865181101562000aec5760008a90036200089e57826200087d8162000fd6565b60008181526001870160205260409020549b50935060079250620008ae9050565b81620008aa8162000fd6565b9250505b6000806000808a8581518110620008c957620008c962000e14565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6200096b5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620003df565b30606082901c03620009d75760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620003df565b600587901b8f901b94506001600160e01b03198086169083161462000a29576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166001600160601b0383161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e016905085821462000a90576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c17905562000ab4565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b8460000362000ad357600086815260018801602052604081208190559c505b505050808062000ae39062000e56565b9150506200085d565b508062000afb83600862000ff0565b62000b07919062001012565b9950505062000b6a565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401620003df565b50959694955050505050565b6001600160a01b03821662000c005780511562000bfc5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401620003df565b5050565b600081511162000c795760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401620003df565b6001600160a01b038216301462000caf5762000caf826040518060600160405280602881526020016200208f6028913962000d9b565b600080836001600160a01b03168360405162000ccc91906200102d565b600060405180830381855af49150503d806000811462000d09576040519150601f19603f3d011682016040523d82523d6000602084013e62000d0e565b606091505b50915091508162000d955780511562000d3d578060405162461bcd60e51b8152600401620003df91906200104b565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401620003df565b50505050565b813b818162000d955760405162461bcd60e51b8152600401620003df91906200104b565b80516001600160a01b038116811462000dd757600080fd5b919050565b6000806040838503121562000df057600080fd5b62000dfb8362000dbf565b915062000e0b6020840162000dbf565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000e6b5762000e6b62000e40565b5060010190565b60005b8381101562000e8f57818101518382015260200162000e75565b8381111562000d955750506000910152565b6000815180845262000ebb81602086016020860162000e72565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000fa457898403607f19018652815180516001600160a01b0316855283810151898601906003811062000f4057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f8e5783516001600160e01b031916825292860192600192909201919086019062000f62565b5097850197955050509082019060010162000ef8565b50506001600160a01b038a1690880152868103604088015262000fc8818962000ea1565b9a9950505050505050505050565b60008162000fe85762000fe862000e40565b506000190190565b60008160001904831182151516156200100d576200100d62000e40565b500290565b6000821982111562001028576200102862000e40565b500190565b600082516200104181846020870162000e72565b9190910192915050565b60208152600062001060602083018462000ea1565b9392505050565b610fb480620010776000396000f3fe60806040523661000b57005b600080356001600160e01b0319168152600080516020610eeb8339815191526020819052604090912054819060601c8061008c5760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460448201526064015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100ab573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020610eeb833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54600080516020610eeb8339815191529061ffff8116908190600090600716156101905750600381901c60009081526001840160205260409020545b60005b87518110156102175761020083838a84815181106101b3576101b3610cb3565b6020026020010151600001518b85815181106101d1576101d1610cb3565b6020026020010151602001518c86815181106101ef576101ef610cb3565b6020026020010151604001516102a3565b90935091508061020f81610cdf565b915050610193565b508282146102335760028401805461ffff191661ffff84161790555b600782161561025557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161028893929190610d66565b60405180910390a161029a8686610a7f565b50505050505050565b60008080600080516020610eeb8339815191529050600084511161031d5760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401610083565b600085600281111561033157610331610cf8565b0361049e5761035886604051806060016040528060248152602001610f0b60249139610c92565b60005b845181101561049857600085828151811061037857610378610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104115760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b6064820152608401610083565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104755760038c901c600090815260018601602052604081209b909b555b8b61047f81610cdf565b9c5050505050808061049090610cdf565b91505061035b565b50610a73565b60018560028111156104b2576104b2610cf8565b036106e1576104d986604051806060016040528060288152602001610f5760289139610c92565b60005b84518110156104985760008582815181106104f9576104f9610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c30810361058e5760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401610083565b896001600160a01b0316816001600160a01b0316036106155760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610083565b6001600160a01b0381166106915760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610083565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b16179055806106d981610cdf565b9150506104dc565b60028560028111156106f5576106f5610cf8565b03610a1b576001600160a01b038616156107705760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b6064820152608401610083565b600388901c6007891660005b86518110156109fb5760008a90036107b8578261079881610e66565b60008181526001870160205260409020549b509350600792506107c69050565b816107c281610e66565b9250505b6000806000808a85815181106107de576107de610cb3565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c61087e5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610083565b30606082901c036108e85760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610083565b600587901b8f901b94506001600160e01b03198086169083161461093e576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146109a3576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c1790556109c7565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b846000036109e557600086815260018801602052604081208190559c505b50505080806109f390610cdf565b91505061077c565b5080610a08836008610e7d565b610a129190610e9c565b99505050610a73565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401610083565b50959694955050505050565b6001600160a01b038216610b0657805115610b025760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401610083565b5050565b6000815111610b7d5760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401610083565b6001600160a01b0382163014610baf57610baf82604051806060016040528060288152602001610f2f60289139610c92565b600080836001600160a01b031683604051610bca9190610eb4565b600060405180830381855af49150503d8060008114610c05576040519150601f19603f3d011682016040523d82523d6000602084013e610c0a565b606091505b509150915081610c8c57805115610c35578060405162461bcd60e51b81526004016100839190610ed0565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401610083565b50505050565b813b8181610c8c5760405162461bcd60e51b81526004016100839190610ed0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610cf157610cf1610cc9565b5060010190565b634e487b7160e01b600052602160045260246000fd5b60005b83811015610d29578181015183820152602001610d11565b83811115610c8c5750506000910152565b60008151808452610d52816020860160208601610d0e565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610e3657898403607f19018652815180516001600160a01b03168552838101518986019060038110610dd557634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610e215783516001600160e01b0319168252928601926001929092019190860190610df7565b50978501979550505090820190600101610d8f565b50506001600160a01b038a16908801528681036040880152610e588189610d3a565b9a9950505050505050505050565b600081610e7557610e75610cc9565b506000190190565b6000816000190483118215151615610e9757610e97610cc9565b500290565b60008219821115610eaf57610eaf610cc9565b500190565b60008251610ec6818460208701610d0e565b9190910192915050565b602081526000610ee36020830184610d3a565b939250505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212204e6b6e58423be59a39c21641051d6bd7ed7f64b27b6fdcbcf32291c98ddd811464736f6c634300080d00334c69624469616d6f6e644375743a2043616e2774207265706c6163652066756ec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212201c0e6f375f8505b9e5db7032e1ce2d96f6ef6969666f191881207364ed6a5e7e64736f6c634300080d0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200005e5760003560e01c806304c01cc7146200006357806394a28f321462000093578063a051e9b314620000c3578063aa9a6e9114620000eb578063e6ee1d4f1462000113575b600080fd5b6200007a6200007436600462000456565b6200013b565b6040516200008a92919062000493565b60405180910390f35b620000aa620000a4366004620004b9565b62000176565b6040516001600160a01b0390911681526020016200008a565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b600081815481106200014c57600080fd5b60009182526020909120600290910201546001600160a01b0381169150600160a01b900460ff1682565b600080307f0000000000000000000000000000000000000000000000000000000000000000604051620001a99062000448565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620001dd573d6000803e3d6000fd5b5090506000604051806101000160405280856020013581526020018560400135815260200185606001358152602001856080013581526020018560a0013581526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018560c001602081019062000264919062000523565b6001600160a01b031681526020016200028160e087018762000543565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509390945250506040519293506001600160a01b03851692631f931c1c92507f00000000000000000000000000000000000000000000000000000000000000009063af52770160e01b9062000307908790602401620005dd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e086901b909216825262000350939291600401620006b8565b600060405180830381600087803b1580156200036b57600080fd5b505af115801562000380573d6000803e3d6000fd5b5050506001600160a01b038316905063f2fde38b620003a3602087018762000523565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620003e557600080fd5b505af1158015620003fa573d6000803e3d6000fd5b50505050816001600160a01b03167f43883daeb0f23afe0fbb9658d1d4c08379520e9654a30f7ea3a9fb3a8f5195bb8560405162000439919062000a2b565b60405180910390a25092915050565b6120df8062000ace83390190565b6000602082840312156200046957600080fd5b5035919050565b600381106200048f57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b038316815260408101620004b2602083018462000470565b9392505050565b600060208284031215620004cc57600080fd5b813567ffffffffffffffff811115620004e457600080fd5b82016101008185031215620004b257600080fd5b6001600160a01b03811681146200050e57600080fd5b50565b80356200051e81620004f8565b919050565b6000602082840312156200053657600080fd5b8135620004b281620004f8565b6000808335601e198436030181126200055b57600080fd5b83018035915067ffffffffffffffff8211156200057757600080fd5b6020019150600581901b36038213156200059057600080fd5b9250929050565b600081518084526020808501945080840160005b83811015620005d25781516001600160a01b031687529582019590820190600101620005ab565b509495945050505050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a083015160018060a01b0380821660c08501528060c08601511660e0850152505060e08301516101008081850152506200065261012084018262000597565b949350505050565b6001600160e01b0319169052565b6000815180845260005b81811015620006905760208185018101518683018201520162000672565b81811115620006a3576000602083870101525b50601f01601f19169290920160200192915050565b60608152600060608201855480825260808401915060808160051b8501018760005260208060002060005b848110156200096d57878403607f1901865281546001600160a01b038116855260608501906200071d85870160a083901c60ff1662000470565b506060604086015260018381018054808452600091825260208083209401905b80600784011015620008055784546200075a838260e01b6200065a565b6001600160e01b031962000777848b0160c084901b83166200065a565b6200078b60408501828460a01b166200065a565b6200079f60608501828460801b166200065a565b620007b360808501828460601b166200065a565b620007c760a08501828460401b166200065a565b620007da60c0850182848d1b166200065a565b620007eb60e085018284166200065a565b50506101008201915083850194506008830192506200073d565b93549380831015620008295762000820828660e01b6200065a565b91830191908701905b8083101562000855576200084c8260c087901b6001600160e01b0319166200065a565b91830191908701905b808310156200088157620008788260a087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008ad57620008a482608087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008d957620008d082606087901b6001600160e01b0319166200065a565b91830191908701905b808310156200090557620008fc82604087901b6001600160e01b0319166200065a565b91830191908701905b808310156200092f576200092682868a1b6001600160e01b0319166200065a565b91830191908701905b8083101562000953576200094e826001600160e01b031987166200065a565b908701905b5098860198965050506002929092019150600101620006e3565b50506001600160a01b03881690860152848103604086015262000991818762000668565b98975050505050505050565b6000808335601e19843603018112620009b557600080fd5b830160208101925035905067ffffffffffffffff811115620009d657600080fd5b8060051b36038313156200059057600080fd5b8183526000602080850194508260005b85811015620005d257813562000a0f81620004f8565b6001600160a01b031687529582019590820190600101620009f9565b602081526000823562000a3e81620004f8565b60018060a01b038116602084015250602083013560408301526040830135606083015260608301356080830152608083013560a083015260a083013560c083015262000a8d60c0840162000511565b6001600160a01b03811660e08401525062000aac60e08401846200099d565b6101008481015262000ac461012085018284620009e9565b9594505050505056fe6080604052604051620020df380380620020df833981016040819052620000269162000ddc565b6200003c826200015660201b620000b01760201c565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620000535750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000c657620000c662000e14565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038516815290810160008152602001828152508260008151811062000119576200011962000e14565b60200260200101819052506200014c82600060405180602001604052806000815250620001da60201b620001331760201c565b5050505062001067565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040516000805160206200204b833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546000805160206200204b8339815191529061ffff811690819060009060071615620002395750600381901c60009081526001840160205260409020545b60005b8751811015620002d557620002bb83838a848151811062000261576200026162000e14565b6020026020010151600001518b858151811062000282576200028262000e14565b6020026020010151602001518c8681518110620002a357620002a362000e14565b6020026020010151604001516200036760201b60201c565b909350915080620002cc8162000e56565b9150506200023c565b50828214620002f25760028401805461ffff191661ffff84161790555b60078216156200031557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200034a9392919062000ecf565b60405180910390a16200035e868662000b76565b50505050505050565b600080806000805160206200204b83398151915290506000845111620003e85760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084015b60405180910390fd5b6000856002811115620003ff57620003ff62000e2a565b0362000585576200042a866040518060600160405280602481526020016200206b6024913962000d9b565b60005b84518110156200057e5760008582815181106200044e576200044e62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c15620004f15760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620003df565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a819003620005565760038c901c600090815260018601602052604081209b909b555b8b620005628162000e56565b9c50505050508080620005759062000e56565b9150506200042d565b5062000b6a565b60018560028111156200059c576200059c62000e2a565b03620007b557620005c786604051806060016040528060288152602001620020b76028913962000d9b565b60005b84518110156200057e576000858281518110620005eb57620005eb62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c308103620006825760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401620003df565b896001600160a01b0316816001600160a01b031603620006fa5760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401620003df565b6001600160a01b038116620007675760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401620003df565b506001600160e01b031990911660009081526020849052604090206001600160601b03919091166001600160601b031960608a901b1617905580620007ac8162000e56565b915050620005ca565b6002856002811115620007cc57620007cc62000e2a565b0362000b11576001600160a01b03861615620008515760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620003df565b600388901c6007891660005b865181101562000aec5760008a90036200089e57826200087d8162000fd6565b60008181526001870160205260409020549b50935060079250620008ae9050565b81620008aa8162000fd6565b9250505b6000806000808a8581518110620008c957620008c962000e14565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6200096b5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620003df565b30606082901c03620009d75760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620003df565b600587901b8f901b94506001600160e01b03198086169083161462000a29576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166001600160601b0383161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e016905085821462000a90576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c17905562000ab4565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b8460000362000ad357600086815260018801602052604081208190559c505b505050808062000ae39062000e56565b9150506200085d565b508062000afb83600862000ff0565b62000b07919062001012565b9950505062000b6a565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401620003df565b50959694955050505050565b6001600160a01b03821662000c005780511562000bfc5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401620003df565b5050565b600081511162000c795760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401620003df565b6001600160a01b038216301462000caf5762000caf826040518060600160405280602881526020016200208f6028913962000d9b565b600080836001600160a01b03168360405162000ccc91906200102d565b600060405180830381855af49150503d806000811462000d09576040519150601f19603f3d011682016040523d82523d6000602084013e62000d0e565b606091505b50915091508162000d955780511562000d3d578060405162461bcd60e51b8152600401620003df91906200104b565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401620003df565b50505050565b813b818162000d955760405162461bcd60e51b8152600401620003df91906200104b565b80516001600160a01b038116811462000dd757600080fd5b919050565b6000806040838503121562000df057600080fd5b62000dfb8362000dbf565b915062000e0b6020840162000dbf565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000e6b5762000e6b62000e40565b5060010190565b60005b8381101562000e8f57818101518382015260200162000e75565b8381111562000d955750506000910152565b6000815180845262000ebb81602086016020860162000e72565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000fa457898403607f19018652815180516001600160a01b0316855283810151898601906003811062000f4057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f8e5783516001600160e01b031916825292860192600192909201919086019062000f62565b5097850197955050509082019060010162000ef8565b50506001600160a01b038a1690880152868103604088015262000fc8818962000ea1565b9a9950505050505050505050565b60008162000fe85762000fe862000e40565b506000190190565b60008160001904831182151516156200100d576200100d62000e40565b500290565b6000821982111562001028576200102862000e40565b500190565b600082516200104181846020870162000e72565b9190910192915050565b60208152600062001060602083018462000ea1565b9392505050565b610fb480620010776000396000f3fe60806040523661000b57005b600080356001600160e01b0319168152600080516020610eeb8339815191526020819052604090912054819060601c8061008c5760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460448201526064015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100ab573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020610eeb833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54600080516020610eeb8339815191529061ffff8116908190600090600716156101905750600381901c60009081526001840160205260409020545b60005b87518110156102175761020083838a84815181106101b3576101b3610cb3565b6020026020010151600001518b85815181106101d1576101d1610cb3565b6020026020010151602001518c86815181106101ef576101ef610cb3565b6020026020010151604001516102a3565b90935091508061020f81610cdf565b915050610193565b508282146102335760028401805461ffff191661ffff84161790555b600782161561025557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161028893929190610d66565b60405180910390a161029a8686610a7f565b50505050505050565b60008080600080516020610eeb8339815191529050600084511161031d5760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401610083565b600085600281111561033157610331610cf8565b0361049e5761035886604051806060016040528060248152602001610f0b60249139610c92565b60005b845181101561049857600085828151811061037857610378610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104115760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b6064820152608401610083565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104755760038c901c600090815260018601602052604081209b909b555b8b61047f81610cdf565b9c5050505050808061049090610cdf565b91505061035b565b50610a73565b60018560028111156104b2576104b2610cf8565b036106e1576104d986604051806060016040528060288152602001610f5760289139610c92565b60005b84518110156104985760008582815181106104f9576104f9610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c30810361058e5760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401610083565b896001600160a01b0316816001600160a01b0316036106155760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610083565b6001600160a01b0381166106915760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610083565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b16179055806106d981610cdf565b9150506104dc565b60028560028111156106f5576106f5610cf8565b03610a1b576001600160a01b038616156107705760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b6064820152608401610083565b600388901c6007891660005b86518110156109fb5760008a90036107b8578261079881610e66565b60008181526001870160205260409020549b509350600792506107c69050565b816107c281610e66565b9250505b6000806000808a85815181106107de576107de610cb3565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c61087e5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610083565b30606082901c036108e85760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610083565b600587901b8f901b94506001600160e01b03198086169083161461093e576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146109a3576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c1790556109c7565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b846000036109e557600086815260018801602052604081208190559c505b50505080806109f390610cdf565b91505061077c565b5080610a08836008610e7d565b610a129190610e9c565b99505050610a73565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401610083565b50959694955050505050565b6001600160a01b038216610b0657805115610b025760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401610083565b5050565b6000815111610b7d5760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401610083565b6001600160a01b0382163014610baf57610baf82604051806060016040528060288152602001610f2f60289139610c92565b600080836001600160a01b031683604051610bca9190610eb4565b600060405180830381855af49150503d8060008114610c05576040519150601f19603f3d011682016040523d82523d6000602084013e610c0a565b606091505b509150915081610c8c57805115610c35578060405162461bcd60e51b81526004016100839190610ed0565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401610083565b50505050565b813b8181610c8c5760405162461bcd60e51b81526004016100839190610ed0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610cf157610cf1610cc9565b5060010190565b634e487b7160e01b600052602160045260246000fd5b60005b83811015610d29578181015183820152602001610d11565b83811115610c8c5750506000910152565b60008151808452610d52816020860160208601610d0e565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610e3657898403607f19018652815180516001600160a01b03168552838101518986019060038110610dd557634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610e215783516001600160e01b0319168252928601926001929092019190860190610df7565b50978501979550505090820190600101610d8f565b50506001600160a01b038a16908801528681036040880152610e588189610d3a565b9a9950505050505050505050565b600081610e7557610e75610cc9565b506000190190565b6000816000190483118215151615610e9757610e97610cc9565b500290565b60008219821115610eaf57610eaf610cc9565b500190565b60008251610ec6818460208701610d0e565b9190910192915050565b602081526000610ee36020830184610d3a565b939250505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212204e6b6e58423be59a39c21641051d6bd7ed7f64b27b6fdcbcf32291c98ddd811464736f6c634300080d00334c69624469616d6f6e644375743a2043616e2774207265706c6163652066756ec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212201c0e6f375f8505b9e5db7032e1ce2d96f6ef6969666f191881207364ed6a5e7e64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "newApplication((address,bytes32,uint256,uint256,uint256,uint256,address,address[]))": { + "params": { + "_appConfig": "application configurations" + }, + "returns": { + "_0": "application address" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "ApplicationCreated(address,(address,bytes32,uint256,uint256,uint256,uint256,address,address[]))": { + "notice": "Event emitted when a new application is deployed" + } + }, + "kind": "user", + "methods": { + "newApplication((address,bytes32,uint256,uint256,uint256,uint256,address,address[]))": { + "notice": "Deploy a new application" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3727, + "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", + "label": "diamondCut", + "offset": 0, + "slot": "0", + "type": "t_array(t_struct(FacetCut)6808_storage)dyn_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes4)dyn_storage": { + "base": "t_bytes4", + "encoding": "dynamic_array", + "label": "bytes4[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(FacetCut)6808_storage)dyn_storage": { + "base": "t_struct(FacetCut)6808_storage", + "encoding": "dynamic_array", + "label": "struct IDiamondCut.FacetCut[]", + "numberOfBytes": "32" + }, + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_enum(FacetCutAction)6799": { + "encoding": "inplace", + "label": "enum IDiamondCut.FacetCutAction", + "numberOfBytes": "1" + }, + "t_struct(FacetCut)6808_storage": { + "encoding": "inplace", + "label": "struct IDiamondCut.FacetCut", + "members": [ + { + "astId": 6801, + "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", + "label": "facetAddress", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 6804, + "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", + "label": "action", + "offset": 20, + "slot": "0", + "type": "t_enum(FacetCutAction)6799" + }, + { + "astId": 6807, + "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", + "label": "functionSelectors", + "offset": 0, + "slot": "1", + "type": "t_array(t_bytes4)dyn_storage" + } + ], + "numberOfBytes": "64" + } + } + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/CartesiMath.json b/echo-js/deployments/localhost/CartesiMath.json new file mode 100644 index 00000000..1db8b0c6 --- /dev/null +++ b/echo-js/deployments/localhost/CartesiMath.json @@ -0,0 +1,218 @@ +{ + "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "clz", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "ctz", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "getLog2Floor", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "getLog2TableTimes1M", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "isPowerOf2", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_num", + "type": "uint256" + } + ], + "name": "log2ApproxTimes1M", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x7ade92f7ba8f601e08c7d0d3c49df65533e1d6cb495b8fcaac7aeef5f63d8659", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "transactionIndex": 0, + "gasUsed": "479702", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x47692e638868cadc92222970bda062e7ea9612e7d7f2fb435e867a9b28ccb718", + "transactionHash": "0x7ade92f7ba8f601e08c7d0d3c49df65533e1d6cb495b8fcaac7aeef5f63d8659", + "logs": [], + "blockNumber": 3, + "cumulativeGasUsed": "479702", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_num\",\"type\":\"uint256\"}],\"name\":\"clz\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_num\",\"type\":\"uint256\"}],\"name\":\"ctz\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_num\",\"type\":\"uint256\"}],\"name\":\"getLog2Floor\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_num\",\"type\":\"uint256\"}],\"name\":\"getLog2TableTimes1M\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_num\",\"type\":\"uint256\"}],\"name\":\"isPowerOf2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_num\",\"type\":\"uint256\"}],\"name\":\"log2ApproxTimes1M\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"clz(uint256)\":{\"details\":\"this a binary search implementation\",\"params\":{\"_num\":\"number you want the clz of\"}},\"ctz(uint256)\":{\"details\":\"this a binary search implementation\",\"params\":{\"_num\":\"number you want the ctz of\"}},\"getLog2Floor(uint256)\":{\"params\":{\"_num\":\"number to take floor(log2) of\"},\"returns\":{\"_0\":\"floor(log2) of _num\"}},\"getLog2TableTimes1M(uint256)\":{\"params\":{\"_num\":\"number to take log2 of\"},\"returns\":{\"_0\":\"result after table look-up\"}},\"isPowerOf2(uint256)\":{\"params\":{\"_num\":\"number to check\"},\"returns\":{\"_0\":\"true if number is power of 2, false if not\"}},\"log2ApproxTimes1M(uint256)\":{\"params\":{\"_num\":\"number to take log2 * 1M of\"},\"returns\":{\"_0\":\"approximate log2 times 1M\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"clz(uint256)\":{\"notice\":\"count leading zeros\"},\"ctz(uint256)\":{\"notice\":\"count trailing zeros\"},\"getLog2Floor(uint256)\":{\"notice\":\"get floor of log2 of number\"},\"getLog2TableTimes1M(uint256)\":{\"notice\":\"navigates log2tableTimes1M\"},\"isPowerOf2(uint256)\":{\"notice\":\"checks if a number is Power of 2\"},\"log2ApproxTimes1M(uint256)\":{\"notice\":\"Approximates log2 * 1M\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/CartesiMath.sol\":\"CartesiMath\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/CartesiMath.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title CartesiMath\\n/// @author Felipe Argento\\npragma solidity ^0.8.0;\\n\\nlibrary CartesiMath {\\n // mapping values are packed as bytes3 each\\n // see test/TestCartesiMath.ts for decimal values\\n bytes constant log2tableTimes1M =\\n hex\\\"0000000F4240182F421E8480236E082771822AD63A2DC6C0305E8532B04834C96736B3C23876D73A187A3B9D4A3D09003E5EA63FA0C540D17741F28843057D440BA745062945F60246DC1047B917488DC7495ABA4A207C4ADF8A4B98544C4B404CF8AA4DA0E64E44434EE3054F7D6D5013B750A61A5134C851BFF05247BD52CC58534DE753CC8D54486954C19C55384255AC75561E50568DE956FB575766B057D00758376F589CFA5900BA5962BC59C3135A21CA5A7EF15ADA945B34BF5B8D805BE4DF5C3AEA5C8FA95CE3265D356C5D86835DD6735E25455E73005EBFAD5F0B525F55F75F9FA25FE85A60302460770860BD0A61023061467F6189FD61CCAE620E98624FBF62902762CFD5630ECD634D12638AA963C7966403DC643F7F647A8264B4E864EEB56527EC6560906598A365D029660724663D9766738566A8F066DDDA6712476746386779AF67ACAF67DF3A6811526842FA68743268A4FC68D55C6905536934E169640A6992CF69C13169EF326A1CD46A4A186A76FF6AA38C6ACFC0\\\";\\n\\n /// @notice Approximates log2 * 1M\\n /// @param _num number to take log2 * 1M of\\n /// @return approximate log2 times 1M\\n function log2ApproxTimes1M(uint256 _num) public pure returns (uint256) {\\n require(_num > 0, \\\"Number cannot be zero\\\");\\n uint256 leading = 0;\\n\\n if (_num == 1) return 0;\\n\\n while (_num > 128) {\\n _num = _num >> 1;\\n leading += 1;\\n }\\n return (leading * uint256(1000000)) + (getLog2TableTimes1M(_num));\\n }\\n\\n /// @notice navigates log2tableTimes1M\\n /// @param _num number to take log2 of\\n /// @return result after table look-up\\n function getLog2TableTimes1M(uint256 _num) public pure returns (uint256) {\\n bytes3 result = 0;\\n for (uint8 i = 0; i < 3; i++) {\\n bytes3 tempResult = log2tableTimes1M[(_num - 1) * 3 + i];\\n result = result | (tempResult >> (i * 8));\\n }\\n\\n return uint256(uint24(result));\\n }\\n\\n /// @notice get floor of log2 of number\\n /// @param _num number to take floor(log2) of\\n /// @return floor(log2) of _num\\n function getLog2Floor(uint256 _num) public pure returns (uint8) {\\n require(_num != 0, \\\"log of zero is undefined\\\");\\n\\n return uint8(255 - clz(_num));\\n }\\n\\n /// @notice checks if a number is Power of 2\\n /// @param _num number to check\\n /// @return true if number is power of 2, false if not\\n function isPowerOf2(uint256 _num) public pure returns (bool) {\\n if (_num == 0) return false;\\n\\n return _num & (_num - 1) == 0;\\n }\\n\\n /// @notice count trailing zeros\\n /// @param _num number you want the ctz of\\n /// @dev this a binary search implementation\\n function ctz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { n = n + 128; _num = _num >> 128; }\\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) { n = n + 64; _num = _num >> 64; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) { n = n + 32; _num = _num >> 32; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) { n = n + 16; _num = _num >> 16; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) { n = n + 8; _num = _num >> 8; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) { n = n + 4; _num = _num >> 4; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) { n = n + 2; _num = _num >> 2; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n\\n /// @notice count leading zeros\\n /// @param _num number you want the clz of\\n /// @dev this a binary search implementation\\n function clz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 == 0) { n = n + 128; _num = _num << 128; }\\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) { n = n + 64; _num = _num << 64; }\\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) { n = n + 32; _num = _num << 32; }\\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 16; _num = _num << 16; }\\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 8; _num = _num << 8; }\\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 4; _num = _num << 4; }\\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 2; _num = _num << 2; }\\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n}\\n\",\"keccak256\":\"0x28b74012e966438edff701decdc5ffd207b3f0244af65fbd7d397050986e58d4\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6107b661003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061006c5760003560e01c806306c8e54b14610071578063296e7af81461009b57806330244f7a146100bc57806332ef283b146100cf578063d82ae4b1146100e2578063e3581b6814610105575b600080fd5b61008461007f36600461053b565b610118565b60405160ff90911681526020015b60405180910390f35b6100ae6100a936600461053b565b610186565b604051908152602001610092565b6100ae6100ca36600461053b565b610297565b6100ae6100dd36600461053b565b6103bc565b6100f56100f036600461053b565b61047b565b6040519015158152602001610092565b6100ae61011336600461053b565b61049e565b60008161016c5760405162461bcd60e51b815260206004820152601860248201527f6c6f67206f66207a65726f20697320756e646566696e6564000000000000000060448201526064015b60405180910390fd5b61017582610297565b6101809060ff6105b3565b92915050565b6000816101965750610100919050565b60006fffffffffffffffffffffffffffffffff83166101c4576101ba816080610553565b9050608083901c92505b67ffffffffffffffff83166101e8576101de816040610553565b9050604083901c92505b63ffffffff8316610208576101fe816020610553565b9050602083901c92505b61ffff83166102265761021c816010610553565b9050601083901c92505b60ff831661024357610239816008610553565b9050600883901c92505b600f831661026057610256816004610553565b9050600483901c92505b6003831661027d57610273816002610553565b9050600283901c92505b6001831661018057610290816001610553565b9392505050565b6000816102a75750610100919050565b60006fffffffffffffffffffffffffffffffff1983166102d6576102cc816080610553565b9050608083901b92505b6001600160c01b031983166102fa576102f0816040610553565b9050604083901b92505b6001600160e01b0319831661031e57610314816020610553565b9050602083901b92505b6001600160f01b0319831661034257610338816010610553565b9050601083901b92505b6001600160f81b031983166103665761035c816008610553565b9050600883901b92505b600f60fc1b83166103865761037c816004610553565b9050600483901b92505b600360fe1b83166103a65761039c816002610553565b9050600283901b92505b600160ff1b831661018057610290816001610553565b600080805b60038160ff161015610471576000604051806101a001604052806101808152602001610601610180913960ff83166103fa6001886105b3565b61040590600361056b565b61040f9190610553565b8151811061042d57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916905061044982600861058a565b60ff16816001600160e81b031916901c83179250508080610469906105ca565b9150506103c1565b5060e81c92915050565b60008161048a57506000919050565b6104956001836105b3565b90911615919050565b60008082116104e75760405162461bcd60e51b81526020600482015260156024820152744e756d6265722063616e6e6f74206265207a65726f60581b6044820152606401610163565b600082600114156104fb5750600092915050565b608083111561051b57600192831c926105149082610553565b90506104fb565b610524836103bc565b610531620f42408361056b565b6102909190610553565b60006020828403121561054c578081fd5b5035919050565b60008219821115610566576105666105ea565b500190565b6000816000190483118215151615610585576105856105ea565b500290565b600060ff821660ff84168160ff04811182151516156105ab576105ab6105ea565b029392505050565b6000828210156105c5576105c56105ea565b500390565b600060ff821660ff8114156105e1576105e16105ea565b60010192915050565b634e487b7160e01b600052601160045260246000fdfe0000000f4240182f421e8480236e082771822ad63a2dc6c0305e8532b04834c96736b3c23876d73a187a3b9d4a3d09003e5ea63fa0c540d17741f28843057d440ba745062945f60246dc1047b917488dc7495aba4a207c4adf8a4b98544c4b404cf8aa4da0e64e44434ee3054f7d6d5013b750a61a5134c851bff05247bd52cc58534de753cc8d54486954c19c55384255ac75561e50568de956fb575766b057d00758376f589cfa5900ba5962bc59c3135a21ca5a7ef15ada945b34bf5b8d805be4df5c3aea5c8fa95ce3265d356c5d86835dd6735e25455e73005ebfad5f0b525f55f75f9fa25fe85a60302460770860bd0a61023061467f6189fd61ccae620e98624fbf62902762cfd5630ecd634d12638aa963c7966403dc643f7f647a8264b4e864eeb56527ec6560906598a365d029660724663d9766738566a8f066ddda6712476746386779af67acaf67df3a6811526842fa68743268a4fc68d55c6905536934e169640a6992cf69c13169ef326a1cd46a4a186a76ff6aa38c6acfc0a26469706673582212209ec06539722b047c33e8d359cfc9b7cd43d1170f471e94162e8503d48b06b59e64736f6c63430008040033", + "deployedBytecode": "0x730000000000000000000000000000000000000000301460806040526004361061006c5760003560e01c806306c8e54b14610071578063296e7af81461009b57806330244f7a146100bc57806332ef283b146100cf578063d82ae4b1146100e2578063e3581b6814610105575b600080fd5b61008461007f36600461053b565b610118565b60405160ff90911681526020015b60405180910390f35b6100ae6100a936600461053b565b610186565b604051908152602001610092565b6100ae6100ca36600461053b565b610297565b6100ae6100dd36600461053b565b6103bc565b6100f56100f036600461053b565b61047b565b6040519015158152602001610092565b6100ae61011336600461053b565b61049e565b60008161016c5760405162461bcd60e51b815260206004820152601860248201527f6c6f67206f66207a65726f20697320756e646566696e6564000000000000000060448201526064015b60405180910390fd5b61017582610297565b6101809060ff6105b3565b92915050565b6000816101965750610100919050565b60006fffffffffffffffffffffffffffffffff83166101c4576101ba816080610553565b9050608083901c92505b67ffffffffffffffff83166101e8576101de816040610553565b9050604083901c92505b63ffffffff8316610208576101fe816020610553565b9050602083901c92505b61ffff83166102265761021c816010610553565b9050601083901c92505b60ff831661024357610239816008610553565b9050600883901c92505b600f831661026057610256816004610553565b9050600483901c92505b6003831661027d57610273816002610553565b9050600283901c92505b6001831661018057610290816001610553565b9392505050565b6000816102a75750610100919050565b60006fffffffffffffffffffffffffffffffff1983166102d6576102cc816080610553565b9050608083901b92505b6001600160c01b031983166102fa576102f0816040610553565b9050604083901b92505b6001600160e01b0319831661031e57610314816020610553565b9050602083901b92505b6001600160f01b0319831661034257610338816010610553565b9050601083901b92505b6001600160f81b031983166103665761035c816008610553565b9050600883901b92505b600f60fc1b83166103865761037c816004610553565b9050600483901b92505b600360fe1b83166103a65761039c816002610553565b9050600283901b92505b600160ff1b831661018057610290816001610553565b600080805b60038160ff161015610471576000604051806101a001604052806101808152602001610601610180913960ff83166103fa6001886105b3565b61040590600361056b565b61040f9190610553565b8151811061042d57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916905061044982600861058a565b60ff16816001600160e81b031916901c83179250508080610469906105ca565b9150506103c1565b5060e81c92915050565b60008161048a57506000919050565b6104956001836105b3565b90911615919050565b60008082116104e75760405162461bcd60e51b81526020600482015260156024820152744e756d6265722063616e6e6f74206265207a65726f60581b6044820152606401610163565b600082600114156104fb5750600092915050565b608083111561051b57600192831c926105149082610553565b90506104fb565b610524836103bc565b610531620f42408361056b565b6102909190610553565b60006020828403121561054c578081fd5b5035919050565b60008219821115610566576105666105ea565b500190565b6000816000190483118215151615610585576105856105ea565b500290565b600060ff821660ff84168160ff04811182151516156105ab576105ab6105ea565b029392505050565b6000828210156105c5576105c56105ea565b500390565b600060ff821660ff8114156105e1576105e16105ea565b60010192915050565b634e487b7160e01b600052601160045260246000fdfe0000000f4240182f421e8480236e082771822ad63a2dc6c0305e8532b04834c96736b3c23876d73a187a3b9d4a3d09003e5ea63fa0c540d17741f28843057d440ba745062945f60246dc1047b917488dc7495aba4a207c4adf8a4b98544c4b404cf8aa4da0e64e44434ee3054f7d6d5013b750a61a5134c851bff05247bd52cc58534de753cc8d54486954c19c55384255ac75561e50568de956fb575766b057d00758376f589cfa5900ba5962bc59c3135a21ca5a7ef15ada945b34bf5b8d805be4df5c3aea5c8fa95ce3265d356c5d86835dd6735e25455e73005ebfad5f0b525f55f75f9fa25fe85a60302460770860bd0a61023061467f6189fd61ccae620e98624fbf62902762cfd5630ecd634d12638aa963c7966403dc643f7f647a8264b4e864eeb56527ec6560906598a365d029660724663d9766738566a8f066ddda6712476746386779af67acaf67df3a6811526842fa68743268a4fc68d55c6905536934e169640a6992cf69c13169ef326a1cd46a4a186a76ff6aa38c6acfc0a26469706673582212209ec06539722b047c33e8d359cfc9b7cd43d1170f471e94162e8503d48b06b59e64736f6c63430008040033", + "devdoc": { + "kind": "dev", + "methods": { + "clz(uint256)": { + "details": "this a binary search implementation", + "params": { + "_num": "number you want the clz of" + } + }, + "ctz(uint256)": { + "details": "this a binary search implementation", + "params": { + "_num": "number you want the ctz of" + } + }, + "getLog2Floor(uint256)": { + "params": { + "_num": "number to take floor(log2) of" + }, + "returns": { + "_0": "floor(log2) of _num" + } + }, + "getLog2TableTimes1M(uint256)": { + "params": { + "_num": "number to take log2 of" + }, + "returns": { + "_0": "result after table look-up" + } + }, + "isPowerOf2(uint256)": { + "params": { + "_num": "number to check" + }, + "returns": { + "_0": "true if number is power of 2, false if not" + } + }, + "log2ApproxTimes1M(uint256)": { + "params": { + "_num": "number to take log2 * 1M of" + }, + "returns": { + "_0": "approximate log2 times 1M" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "clz(uint256)": { + "notice": "count leading zeros" + }, + "ctz(uint256)": { + "notice": "count trailing zeros" + }, + "getLog2Floor(uint256)": { + "notice": "get floor of log2 of number" + }, + "getLog2TableTimes1M(uint256)": { + "notice": "navigates log2tableTimes1M" + }, + "isPowerOf2(uint256)": { + "notice": "checks if a number is Power of 2" + }, + "log2ApproxTimes1M(uint256)": { + "notice": "Approximates log2 * 1M" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/CartesiToken.json b/echo-js/deployments/localhost/CartesiToken.json new file mode 100644 index 00000000..02fb264c --- /dev/null +++ b/echo-js/deployments/localhost/CartesiToken.json @@ -0,0 +1,536 @@ +{ + "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "sender", + "type": "address" + }, + { + "name": "recipient", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "DECIMALS", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INITIAL_SUPPLY", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "account", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_extraLockTime", + "type": "uint256" + } + ], + "name": "extendMintLockTime", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "addMinter", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceMinter", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "NAME", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "recipient", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "isMinter", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "SYMBOL", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "extendedBy", + "type": "uint256" + }, + { + "indexed": false, + "name": "deadline", + "type": "uint256" + } + ], + "name": "LocktimeExteded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "account", + "type": "address" + } + ], + "name": "MinterAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "account", + "type": "address" + } + ], + "name": "MinterRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + } + ], + "transactionHash": "0x9e6456832276fd0e80320a2f6f772142620914632ca43399920bfb8fcf4b5643", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "transactionIndex": 0, + "gasUsed": "1770294", + "logsBloom": "0x00800000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000010040000010000000000000000000000020000000000000100000800000000008000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000200000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x16d422a59cdd3487a977f9bde8985c98045f873d2595dde9c5263a5f4d3575e2", + "transactionHash": "0x9e6456832276fd0e80320a2f6f772142620914632ca43399920bfb8fcf4b5643", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 8, + "transactionHash": "0x9e6456832276fd0e80320a2f6f772142620914632ca43399920bfb8fcf4b5643", + "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "topics": [ + "0x6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f6", + "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x16d422a59cdd3487a977f9bde8985c98045f873d2595dde9c5263a5f4d3575e2" + }, + { + "transactionIndex": 0, + "blockNumber": 8, + "transactionHash": "0x9e6456832276fd0e80320a2f6f772142620914632ca43399920bfb8fcf4b5643", + "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + ], + "data": "0x0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000", + "logIndex": 1, + "blockHash": "0x16d422a59cdd3487a977f9bde8985c98045f873d2595dde9c5263a5f4d3575e2" + } + ], + "blockNumber": 8, + "cumulativeGasUsed": "1770294", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "bytecode": "0x60806040523480156200001157600080fd5b506040518060400160405280600d81526020017f4361727465736920546f6b656e000000000000000000000000000000000000008152506040518060400160405280600481526020017f43545349000000000000000000000000000000000000000000000000000000008152506012620000a0620000946200011c60201b60201c565b6200012460201b60201c565b8260049080519060200190620000b8929190620005a4565b508160059080519060200190620000d1929190620005a4565b5080600660006101000a81548160ff021916908360ff160217905550505050426008819055506200011633601260ff16600a0a633b9aca00026200018560201b60201c565b62000653565b600033905090565b6200013f8160036200035160201b620018971790919060201c565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156200022b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b62000247816002546200043760201b620014bc1790919060201c565b600281905550620002a5816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200043760201b620014bc1790919060201c565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b620003638282620004c260201b60201c565b151515620003d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f526f6c65733a206163636f756e7420616c72656164792068617320726f6c650081525060200191505060405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000808284019050838110151515620004b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156200054d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180620022366022913960400191505060405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005e757805160ff191683800117855562000618565b8280016001018555821562000618579182015b8281111562000617578251825591602001919060010190620005fa565b5b5090506200062791906200062b565b5090565b6200065091905b808211156200064c57600081600090555060010162000632565b5090565b90565b611bd380620006636000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806370a08231116100ad578063a457c2d711610071578063a457c2d7146105ca578063a9059cbb14610630578063aa271e1a14610696578063dd62ed3e146106f2578063f76f8d781461076a5761012c565b806370a082311461041e57806395d89b4114610476578063983b2d56146104f9578063986502751461053d578063a3f4df7e146105475761012c565b80632ff2e9dc116100f45780632ff2e9dc146102e2578063313ce56714610300578063395093511461032457806340c10f191461038a578063681db92e146103f05761012c565b806306fdde0314610131578063095ea7b3146101b457806318160ddd1461021a57806323b872dd146102385780632e0f2625146102be575b600080fd5b6101396107ed565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017957808201518184015260208101905061015e565b50505050905090810190601f1680156101a65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610200600480360360408110156101ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061088f565b604051808215151515815260200191505060405180910390f35b6102226108ad565b6040518082815260200191505060405180910390f35b6102a46004803603606081101561024e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108b7565b604051808215151515815260200191505060405180910390f35b6102c6610990565b604051808260ff1660ff16815260200191505060405180910390f35b6102ea610995565b6040518082815260200191505060405180910390f35b6103086109a6565b604051808260ff1660ff16815260200191505060405180910390f35b6103706004803603604081101561033a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506109bd565b604051808215151515815260200191505060405180910390f35b6103d6600480360360408110156103a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a70565b604051808215151515815260200191505060405180910390f35b61041c6004803603602081101561040657600080fd5b8101908080359060200190929190505050610b0c565b005b6104606004803603602081101561043457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bcd565b6040518082815260200191505060405180910390f35b61047e610c15565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104be5780820151818401526020810190506104a3565b50505050905090810190601f1680156104eb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61053b6004803603602081101561050f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cb7565b005b610545610d2a565b005b61054f610d3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561058f578082015181840152602081019050610574565b50505050905090810190601f1680156105bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610616600480360360408110156105e057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d75565b604051808215151515815260200191505060405180910390f35b61067c6004803603604081101561064657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e42565b604051808215151515815260200191505060405180910390f35b6106d8600480360360208110156106ac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e60565b604051808215151515815260200191505060405180910390f35b6107546004803603604081101561070857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e7d565b6040518082815260200191505060405180910390f35b610772610f04565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156107b2578082015181840152602081019050610797565b50505050905090810190601f1680156107df5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108855780601f1061085a57610100808354040283529160200191610885565b820191906000526020600020905b81548152906001019060200180831161086857829003601f168201915b5050505050905090565b60006108a361089c610f3d565b8484610f45565b6001905092915050565b6000600254905090565b60006108c4848484611140565b610985846108d0610f3d565b61098085604051806060016040528060288152602001611af060289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610936610f3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113fa9092919063ffffffff16565b610f45565b600190509392505050565b601281565b601260ff16600a0a633b9aca000281565b6000600660009054906101000a900460ff16905090565b6000610a666109ca610f3d565b84610a6185600160006109db610f3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114bc90919063ffffffff16565b610f45565b6001905092915050565b6000610a82610a7d610f3d565b610e60565b1515610ad9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611a9f6030913960400191505060405180910390fd5b610ae76008546007546114bc565b421015610af75760009050610b06565b610b018383611546565b600190505b92915050565b610b1c610b17610f3d565b610e60565b1515610b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611a9f6030913960400191505060405180910390fd5b610b7f600754826114bc565b6007819055507fd04bb4a40cc3220e8987e72af12aa925741bb256bc68dd2d13dc6c524f8873838160075460085401604051808381526020018281526020019250505060405180910390a150565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610cad5780601f10610c8257610100808354040283529160200191610cad565b820191906000526020600020905b815481529060010190602001808311610c9057829003601f168201915b5050505050905090565b610cc7610cc2610f3d565b610e60565b1515610d1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611a9f6030913960400191505060405180910390fd5b610d2781611703565b50565b610d3a610d35610f3d565b61175d565b565b6040518060400160405280600d81526020017f4361727465736920546f6b656e0000000000000000000000000000000000000081525081565b6000610e38610d82610f3d565b84610e3385604051806060016040528060258152602001611b836025913960016000610dac610f3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113fa9092919063ffffffff16565b610f45565b6001905092915050565b6000610e56610e4f610f3d565b8484611140565b6001905092915050565b6000610e768260036117b790919063ffffffff16565b9050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6040518060400160405280600481526020017f435453490000000000000000000000000000000000000000000000000000000081525081565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610fcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180611b5f6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611055576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611a576022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156111c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180611b3a6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611250576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611a346023913960400191505060405180910390fd5b6112bb81604051806060016040528060268152602001611a79602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113fa9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061134e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114bc90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b600083831115829015156114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561146e578082015181840152602081019050611453565b50505050905090810190601f16801561149b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015151561153c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156115eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b611600816002546114bc90919063ffffffff16565b600281905550611657816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114bc90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b61171781600361189790919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b61177181600361197490919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611840576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611b186022913960400191505060405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6118a182826117b7565b151515611916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f526f6c65733a206163636f756e7420616c72656164792068617320726f6c650081525060200191505060405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b61197e82826117b7565b15156119d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180611acf6021913960400191505060405180910390fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63654d696e746572526f6c653a2063616c6c657220646f6573206e6f74206861766520746865204d696e74657220726f6c65526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c6545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa165627a7a7230582039dfb521b3deb59a807433e03ea4df6a14208a5489093b57b445fb0fd7c6935e0029526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c806370a08231116100ad578063a457c2d711610071578063a457c2d7146105ca578063a9059cbb14610630578063aa271e1a14610696578063dd62ed3e146106f2578063f76f8d781461076a5761012c565b806370a082311461041e57806395d89b4114610476578063983b2d56146104f9578063986502751461053d578063a3f4df7e146105475761012c565b80632ff2e9dc116100f45780632ff2e9dc146102e2578063313ce56714610300578063395093511461032457806340c10f191461038a578063681db92e146103f05761012c565b806306fdde0314610131578063095ea7b3146101b457806318160ddd1461021a57806323b872dd146102385780632e0f2625146102be575b600080fd5b6101396107ed565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017957808201518184015260208101905061015e565b50505050905090810190601f1680156101a65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610200600480360360408110156101ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061088f565b604051808215151515815260200191505060405180910390f35b6102226108ad565b6040518082815260200191505060405180910390f35b6102a46004803603606081101561024e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108b7565b604051808215151515815260200191505060405180910390f35b6102c6610990565b604051808260ff1660ff16815260200191505060405180910390f35b6102ea610995565b6040518082815260200191505060405180910390f35b6103086109a6565b604051808260ff1660ff16815260200191505060405180910390f35b6103706004803603604081101561033a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506109bd565b604051808215151515815260200191505060405180910390f35b6103d6600480360360408110156103a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a70565b604051808215151515815260200191505060405180910390f35b61041c6004803603602081101561040657600080fd5b8101908080359060200190929190505050610b0c565b005b6104606004803603602081101561043457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bcd565b6040518082815260200191505060405180910390f35b61047e610c15565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104be5780820151818401526020810190506104a3565b50505050905090810190601f1680156104eb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61053b6004803603602081101561050f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cb7565b005b610545610d2a565b005b61054f610d3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561058f578082015181840152602081019050610574565b50505050905090810190601f1680156105bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610616600480360360408110156105e057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d75565b604051808215151515815260200191505060405180910390f35b61067c6004803603604081101561064657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e42565b604051808215151515815260200191505060405180910390f35b6106d8600480360360208110156106ac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e60565b604051808215151515815260200191505060405180910390f35b6107546004803603604081101561070857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e7d565b6040518082815260200191505060405180910390f35b610772610f04565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156107b2578082015181840152602081019050610797565b50505050905090810190601f1680156107df5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108855780601f1061085a57610100808354040283529160200191610885565b820191906000526020600020905b81548152906001019060200180831161086857829003601f168201915b5050505050905090565b60006108a361089c610f3d565b8484610f45565b6001905092915050565b6000600254905090565b60006108c4848484611140565b610985846108d0610f3d565b61098085604051806060016040528060288152602001611af060289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610936610f3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113fa9092919063ffffffff16565b610f45565b600190509392505050565b601281565b601260ff16600a0a633b9aca000281565b6000600660009054906101000a900460ff16905090565b6000610a666109ca610f3d565b84610a6185600160006109db610f3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114bc90919063ffffffff16565b610f45565b6001905092915050565b6000610a82610a7d610f3d565b610e60565b1515610ad9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611a9f6030913960400191505060405180910390fd5b610ae76008546007546114bc565b421015610af75760009050610b06565b610b018383611546565b600190505b92915050565b610b1c610b17610f3d565b610e60565b1515610b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611a9f6030913960400191505060405180910390fd5b610b7f600754826114bc565b6007819055507fd04bb4a40cc3220e8987e72af12aa925741bb256bc68dd2d13dc6c524f8873838160075460085401604051808381526020018281526020019250505060405180910390a150565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610cad5780601f10610c8257610100808354040283529160200191610cad565b820191906000526020600020905b815481529060010190602001808311610c9057829003601f168201915b5050505050905090565b610cc7610cc2610f3d565b610e60565b1515610d1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611a9f6030913960400191505060405180910390fd5b610d2781611703565b50565b610d3a610d35610f3d565b61175d565b565b6040518060400160405280600d81526020017f4361727465736920546f6b656e0000000000000000000000000000000000000081525081565b6000610e38610d82610f3d565b84610e3385604051806060016040528060258152602001611b836025913960016000610dac610f3d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113fa9092919063ffffffff16565b610f45565b6001905092915050565b6000610e56610e4f610f3d565b8484611140565b6001905092915050565b6000610e768260036117b790919063ffffffff16565b9050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6040518060400160405280600481526020017f435453490000000000000000000000000000000000000000000000000000000081525081565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610fcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180611b5f6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611055576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611a576022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156111c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180611b3a6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611250576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611a346023913960400191505060405180910390fd5b6112bb81604051806060016040528060268152602001611a79602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113fa9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061134e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114bc90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b600083831115829015156114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561146e578082015181840152602081019050611453565b50505050905090810190601f16801561149b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015151561153c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156115eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b611600816002546114bc90919063ffffffff16565b600281905550611657816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114bc90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b61171781600361189790919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b61177181600361197490919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611840576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611b186022913960400191505060405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6118a182826117b7565b151515611916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f526f6c65733a206163636f756e7420616c72656164792068617320726f6c650081525060200191505060405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b61197e82826117b7565b15156119d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180611acf6021913960400191505060405180910390fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63654d696e746572526f6c653a2063616c6c657220646f6573206e6f74206861766520746865204d696e74657220726f6c65526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c6545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa165627a7a7230582039dfb521b3deb59a807433e03ea4df6a14208a5489093b57b445fb0fd7c6935e0029", + "devdoc": { + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. * Requirements: * - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). * Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. * NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. * This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. * Emits an {Approval} event indicating the updated allowance. * Requirements: * - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. * This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. * Emits an {Approval} event indicating the updated allowance. * Requirements: * - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. * Requirements: * - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. * Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; * Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for `sender`'s tokens of at least `amount`." + } + } + }, + "userdoc": { + "methods": {} + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/DiamondCutFacet.json b/echo-js/deployments/localhost/DiamondCutFacet.json new file mode 100644 index 00000000..9aed6615 --- /dev/null +++ b/echo-js/deployments/localhost/DiamondCutFacet.json @@ -0,0 +1,135 @@ +{ + "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf1db64dae4b3bed35faa7eeb7a4a29da3f2fb1e7c18323ce214062c1e38dbe27", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "transactionIndex": 0, + "gasUsed": "1068415", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8dab3765f00ac1fef5910658c774e1152421154187b3688ba3ab967f44c027be", + "transactionHash": "0xf1db64dae4b3bed35faa7eeb7a4a29da3f2fb1e7c18323ce214062c1e38dbe27", + "logs": [], + "blockNumber": 12, + "cumulativeGasUsed": "1068415", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorCount >> 3\\\" is a gas efficient division by 8 \\\"selectorCount / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = LibDiamond\\n .addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorCount >> 3\\\" is a gas efficient division by 8 \\\"selectorCount / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n LibDiamond.initializeDiamondCut(_init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x8cfd33aae7e3c4209777364ce776d944511d6110223c3f03f2e7a6ed4646d8cc\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\\n}\\n\",\"keccak256\":\"0x6a3129be1f39b6fec871f2c94bf7debf2d6a4e665547a4d83e7f2def38359e44\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] diamondCut,\\n address init,\\n bytes callData\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x740ea3845282f09bb822e66a189ed431ac799ab08184de7457ef53799b2e99d6\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061125e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e366004610d90565b610045565b005b61004d61027b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e547fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c9061ffff8116908190600090600716156100bc5750600381901c60009081526001840160205260409020545b60005b888110156101b35761019c83838c8c858181106100de576100de610e42565b90506020028101906100f09190610e58565b6100fe906020810190610e78565b8d8d8681811061011057610110610e42565b90506020028101906101229190610e58565b610133906040810190602001610ea9565b8e8e8781811061014557610145610e42565b90506020028101906101579190610e58565b610165906040810190610ec4565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061030992505050565b9093509150806101ab81610f24565b9150506100bf565b508282146101cf5760028401805461ffff191661ffff84161790555b60078216156101f157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738989898989604051610228959493929190610fcc565b60405180910390a16102708787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610af792505050565b505050505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b031633146103075760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b565b600080807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c905060008451116103955760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084016102fe565b60008560028111156103a9576103a9610f3d565b03610516576103d0866040518060600160405280602481526020016111b560249139610d0a565b60005b84518110156105105760008582815181106103f0576103f0610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104895760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b60648201526084016102fe565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104ed5760038c901c600090815260018601602052604081209b909b555b8b6104f781610f24565b9c5050505050808061050890610f24565b9150506103d3565b50610aeb565b600185600281111561052a5761052a610f3d565b03610759576105518660405180606001604052806028815260200161120160289139610d0a565b60005b845181101561051057600085828151811061057157610571610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c3081036106065760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b60648201526084016102fe565b896001600160a01b0316816001600160a01b03160361068d5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016102fe565b6001600160a01b0381166107095760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016102fe565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b161790558061075181610f24565b915050610554565b600285600281111561076d5761076d610f3d565b03610a93576001600160a01b038616156107e85760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b60648201526084016102fe565b600388901c6007891660005b8651811015610a735760008a90036108305782610810816110f5565b60008181526001870160205260409020549b5093506007925061083e9050565b8161083a816110f5565b9250505b6000806000808a858151811061085657610856610e42565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6108f65760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016102fe565b30606082901c036109605760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b60648201526084016102fe565b600587901b8f901b94506001600160e01b0319808616908316146109b6576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214610a1b576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c179055610a3f565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b84600003610a5d57600086815260018801602052604081208190559c505b5050508080610a6b90610f24565b9150506107f4565b5080610a8083600861110c565b610a8a919061112b565b99505050610aeb565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084016102fe565b50959694955050505050565b6001600160a01b038216610b7e57805115610b7a5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d7074790000000060648201526084016102fe565b5050565b6000815111610bf55760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f74206164647265737328302900000060648201526084016102fe565b6001600160a01b0382163014610c2757610c27826040518060600160405280602881526020016111d960289139610d0a565b600080836001600160a01b031683604051610c42919061116f565b600060405180830381855af49150503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b509150915081610d0457805115610cad578060405162461bcd60e51b81526004016102fe9190611181565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b60648201526084016102fe565b50505050565b813b8181610d045760405162461bcd60e51b81526004016102fe9190611181565b80356001600160a01b0381168114610d4257600080fd5b919050565b60008083601f840112610d5957600080fd5b50813567ffffffffffffffff811115610d7157600080fd5b602083019150836020828501011115610d8957600080fd5b9250929050565b600080600080600060608688031215610da857600080fd5b853567ffffffffffffffff80821115610dc057600080fd5b818801915088601f830112610dd457600080fd5b813581811115610de357600080fd5b8960208260051b8501011115610df857600080fd5b60208301975080965050610e0e60208901610d2b565b94506040880135915080821115610e2457600080fd5b50610e3188828901610d47565b969995985093965092949392505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112610e6e57600080fd5b9190910192915050565b600060208284031215610e8a57600080fd5b610e9382610d2b565b9392505050565b803560038110610d4257600080fd5b600060208284031215610ebb57600080fd5b610e9382610e9a565b6000808335601e19843603018112610edb57600080fd5b83018035915067ffffffffffffffff821115610ef657600080fd5b6020019150600581901b3603821315610d8957600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610f3657610f36610f0e565b5060010190565b634e487b7160e01b600052602160045260246000fd5b818352600060208085019450826000805b86811015610f975782356001600160e01b03198116808214610f84578384fd5b8952509683019691830191600101610f64565b50959695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060808252818101869052600090600560808085019089831b8601018a855b8b8110156110c257878303607f190184528135368e9003605e1901811261101157600080fd5b8d016001600160a01b0361102482610d2b565b1684526020611034818301610e9a565b6003811061105257634e487b7160e01b600052602160045260246000fd5b8582015260408281013536849003601e1901811261106f57600080fd5b8301803567ffffffffffffffff81111561108857600080fd5b808a1b360385131561109957600080fd5b8a838901526110ad8b890182868501610f53565b98840198975050509301925050600101610feb565b50506001600160a01b038916602087015285810360408701526110e681888a610fa3565b9b9a5050505050505050505050565b60008161110457611104610f0e565b506000190190565b600081600019048311821515161561112657611126610f0e565b500290565b6000821982111561113e5761113e610f0e565b500190565b60005b8381101561115e578181015183820152602001611146565b83811115610d045750506000910152565b60008251610e6e818460208701611143565b60208152600082518060208401526111a0816040850160208701611143565b601f01601f1916919091016040019291505056fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212204b8b2c4cc9333af346d73b2e4a6dca4f76dd4c5bea51a13e8742c5f94ad18f9f64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e366004610d90565b610045565b005b61004d61027b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e547fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c9061ffff8116908190600090600716156100bc5750600381901c60009081526001840160205260409020545b60005b888110156101b35761019c83838c8c858181106100de576100de610e42565b90506020028101906100f09190610e58565b6100fe906020810190610e78565b8d8d8681811061011057610110610e42565b90506020028101906101229190610e58565b610133906040810190602001610ea9565b8e8e8781811061014557610145610e42565b90506020028101906101579190610e58565b610165906040810190610ec4565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061030992505050565b9093509150806101ab81610f24565b9150506100bf565b508282146101cf5760028401805461ffff191661ffff84161790555b60078216156101f157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738989898989604051610228959493929190610fcc565b60405180910390a16102708787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610af792505050565b505050505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b031633146103075760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b565b600080807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c905060008451116103955760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084016102fe565b60008560028111156103a9576103a9610f3d565b03610516576103d0866040518060600160405280602481526020016111b560249139610d0a565b60005b84518110156105105760008582815181106103f0576103f0610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104895760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b60648201526084016102fe565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104ed5760038c901c600090815260018601602052604081209b909b555b8b6104f781610f24565b9c5050505050808061050890610f24565b9150506103d3565b50610aeb565b600185600281111561052a5761052a610f3d565b03610759576105518660405180606001604052806028815260200161120160289139610d0a565b60005b845181101561051057600085828151811061057157610571610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c3081036106065760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b60648201526084016102fe565b896001600160a01b0316816001600160a01b03160361068d5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016102fe565b6001600160a01b0381166107095760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016102fe565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b161790558061075181610f24565b915050610554565b600285600281111561076d5761076d610f3d565b03610a93576001600160a01b038616156107e85760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b60648201526084016102fe565b600388901c6007891660005b8651811015610a735760008a90036108305782610810816110f5565b60008181526001870160205260409020549b5093506007925061083e9050565b8161083a816110f5565b9250505b6000806000808a858151811061085657610856610e42565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6108f65760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016102fe565b30606082901c036109605760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b60648201526084016102fe565b600587901b8f901b94506001600160e01b0319808616908316146109b6576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214610a1b576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c179055610a3f565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b84600003610a5d57600086815260018801602052604081208190559c505b5050508080610a6b90610f24565b9150506107f4565b5080610a8083600861110c565b610a8a919061112b565b99505050610aeb565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084016102fe565b50959694955050505050565b6001600160a01b038216610b7e57805115610b7a5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d7074790000000060648201526084016102fe565b5050565b6000815111610bf55760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f74206164647265737328302900000060648201526084016102fe565b6001600160a01b0382163014610c2757610c27826040518060600160405280602881526020016111d960289139610d0a565b600080836001600160a01b031683604051610c42919061116f565b600060405180830381855af49150503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b509150915081610d0457805115610cad578060405162461bcd60e51b81526004016102fe9190611181565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b60648201526084016102fe565b50505050565b813b8181610d045760405162461bcd60e51b81526004016102fe9190611181565b80356001600160a01b0381168114610d4257600080fd5b919050565b60008083601f840112610d5957600080fd5b50813567ffffffffffffffff811115610d7157600080fd5b602083019150836020828501011115610d8957600080fd5b9250929050565b600080600080600060608688031215610da857600080fd5b853567ffffffffffffffff80821115610dc057600080fd5b818801915088601f830112610dd457600080fd5b813581811115610de357600080fd5b8960208260051b8501011115610df857600080fd5b60208301975080965050610e0e60208901610d2b565b94506040880135915080821115610e2457600080fd5b50610e3188828901610d47565b969995985093965092949392505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112610e6e57600080fd5b9190910192915050565b600060208284031215610e8a57600080fd5b610e9382610d2b565b9392505050565b803560038110610d4257600080fd5b600060208284031215610ebb57600080fd5b610e9382610e9a565b6000808335601e19843603018112610edb57600080fd5b83018035915067ffffffffffffffff821115610ef657600080fd5b6020019150600581901b3603821315610d8957600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610f3657610f36610f0e565b5060010190565b634e487b7160e01b600052602160045260246000fd5b818352600060208085019450826000805b86811015610f975782356001600160e01b03198116808214610f84578384fd5b8952509683019691830191600101610f64565b50959695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060808252818101869052600090600560808085019089831b8601018a855b8b8110156110c257878303607f190184528135368e9003605e1901811261101157600080fd5b8d016001600160a01b0361102482610d2b565b1684526020611034818301610e9a565b6003811061105257634e487b7160e01b600052602160045260246000fd5b8582015260408281013536849003601e1901811261106f57600080fd5b8301803567ffffffffffffffff81111561108857600080fd5b808a1b360385131561109957600080fd5b8a838901526110ad8b890182868501610f53565b98840198975050509301925050600101610feb565b50506001600160a01b038916602087015285810360408701526110e681888a610fa3565b9b9a5050505050505050505050565b60008161110457611104610f0e565b506000190190565b600081600019048311821515161561112657611126610f0e565b500290565b6000821982111561113e5761113e610f0e565b500190565b60005b8381101561115e578181015183820152602001611146565b83811115610d045750506000910152565b60008251610e6e818460208701611143565b60208152600082518060208401526111a0816040850160208701611143565b601f01601f1916919091016040019291505056fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212204b8b2c4cc9333af346d73b2e4a6dca4f76dd4c5bea51a13e8742c5f94ad18f9f64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_calldata": "A function call, including function selector and arguments _calldata is executed with delegatecall on _init", + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/DiamondInit.json b/echo-js/deployments/localhost/DiamondInit.json new file mode 100644 index 00000000..06524d03 --- /dev/null +++ b/echo-js/deployments/localhost/DiamondInit.json @@ -0,0 +1,176 @@ +{ + "address": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feePerClaim", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeManagerBank", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeManagerOwner", + "type": "address" + } + ], + "name": "FeeManagerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "inputDuration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + } + ], + "name": "RollupsInitialized", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "templateHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "inputDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputLog2Size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feePerClaim", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeManagerBank", + "type": "address" + }, + { + "internalType": "address", + "name": "feeManagerOwner", + "type": "address" + }, + { + "internalType": "address payable[]", + "name": "validators", + "type": "address[]" + } + ], + "internalType": "struct DiamondConfig", + "name": "_dConfig", + "type": "tuple" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x0043e0f7ea63d055c67e444b35395305aeedcdb5eef5f28f22825ddb11581b93", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933", + "transactionIndex": 0, + "gasUsed": "644157", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x03b7f7b6d3ae79074203c186eedfec931fa9dd9af10c068ca1dedc090f0c752d", + "transactionHash": "0x0043e0f7ea63d055c67e444b35395305aeedcdb5eef5f28f22825ddb11581b93", + "logs": [], + "blockNumber": 30, + "cumulativeGasUsed": "644157", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feePerClaim\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeManagerBank\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeManagerOwner\",\"type\":\"address\"}],\"name\":\"FeeManagerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"inputDuration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"challengePeriod\",\"type\":\"uint256\"}],\"name\":\"RollupsInitialized\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"templateHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"inputDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"challengePeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inputLog2Size\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePerClaim\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"feeManagerBank\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeManagerOwner\",\"type\":\"address\"},{\"internalType\":\"address payable[]\",\"name\":\"validators\",\"type\":\"address[]\"}],\"internalType\":\"struct DiamondConfig\",\"name\":\"_dConfig\",\"type\":\"tuple\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"FeeManagerInitialized(uint256,address,address)\":{\"params\":{\"feeManagerBank\":\"fee manager bank address\",\"feeManagerOwner\":\"fee manager owner address\",\"feePerClaim\":\"fee per claim to reward the validators\"}},\"RollupsInitialized(uint256,uint256)\":{\"params\":{\"challengePeriod\":\"duration of challenge period in seconds\",\"inputDuration\":\"duration of input accumulation phase in seconds\"}}},\"kind\":\"dev\",\"methods\":{\"init((bytes32,uint256,uint256,uint256,uint256,address,address,address[]))\":{\"params\":{\"_dConfig\":\"diamond configurations\"}}},\"version\":1},\"userdoc\":{\"events\":{\"FeeManagerInitialized(uint256,address,address)\":{\"notice\":\"FeeManagerImpl contract initialized\"},\"RollupsInitialized(uint256,uint256)\":{\"notice\":\"rollups contract initialized\"}},\"kind\":\"user\",\"methods\":{\"init((bytes32,uint256,uint256,uint256,uint256,address,address,address[]))\":{\"notice\":\"initialize the diamond\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/upgrade_initializers/DiamondInit.sol\":\"DiamondInit\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\\n}\\n\",\"keccak256\":\"0x6a3129be1f39b6fec871f2c94bf7debf2d6a4e665547a4d83e7f2def38359e44\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet)\\n external\\n view\\n returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector)\\n external\\n view\\n returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd6c3796a7c45baea6e47fdd5f2cec95d7796991bc9a949604f99875590962a67\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0xc47289cda9c9cdb749612eb82ccb9abf9ab08dca74bdca22292ae7f765a15a5f\",\"license\":\"MIT\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] diamondCut,\\n address init,\\n bytes callData\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x740ea3845282f09bb822e66a189ed431ac799ab08184de7457ef53799b2e99d6\",\"license\":\"MIT\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"},\"contracts/upgrade_initializers/DiamondInit.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Diamond Initialization Contract\\npragma solidity ^0.8.0;\\n\\n// Rollups-related dependencies\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\n// Diamond-related dependencies\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {IDiamondLoupe} from \\\"../interfaces/IDiamondLoupe.sol\\\";\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\nimport {IERC173} from \\\"../interfaces/IERC173.sol\\\"; // not in openzeppelin-contracts yet\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\n/// @notice diamond configurations\\n/// @param templateHash state hash of the cartesi machine at t0\\n/// @param inputDuration duration of input accumulation phase in seconds\\n/// @param challengePeriod duration of challenge period in seconds\\n/// @param inputLog2Size size of the input memory range in this machine\\n/// @param feePerClaim fee per claim to reward the validators\\n/// @param feeManagerBank fee manager bank address\\n/// @param feeManagerOwner fee manager owner address\\n/// @param validators initial validator set\\n/// @dev validators have to be unique, if the same validator is added twice\\n/// consensus will never be reached\\nstruct DiamondConfig {\\n // RollupsFacet\\n bytes32 templateHash;\\n uint256 inputDuration;\\n uint256 challengePeriod;\\n // InputFacet\\n uint256 inputLog2Size;\\n // FeeManagerFacet\\n uint256 feePerClaim;\\n address feeManagerBank;\\n address feeManagerOwner;\\n // ValidatorManagerFacet\\n address payable[] validators;\\n}\\n\\ncontract DiamondInit {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibInput for LibInput.DiamondStorage;\\n\\n /// @notice initialize the diamond\\n /// @param _dConfig diamond configurations\\n function init(DiamondConfig calldata _dConfig) external {\\n initERC165();\\n initValidatorManager(_dConfig.validators);\\n initRollups(\\n _dConfig.templateHash,\\n _dConfig.inputDuration,\\n _dConfig.challengePeriod\\n );\\n initFeeManager(\\n _dConfig.feePerClaim,\\n _dConfig.feeManagerBank,\\n _dConfig.feeManagerOwner\\n );\\n initInput(_dConfig.inputLog2Size);\\n }\\n\\n /// @notice initialize ERC165 data\\n function initERC165() private {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n ds.supportedInterfaces[type(IERC165).interfaceId] = true;\\n ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;\\n ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;\\n ds.supportedInterfaces[type(IERC173).interfaceId] = true;\\n }\\n\\n /// @notice initalize the Input facet\\n /// @param _inputLog2Size size of the input memory range in this machine\\n function initInput(uint256 _inputLog2Size) private {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n\\n require(\\n _inputLog2Size >= 3 && _inputLog2Size <= 64,\\n \\\"Log of input size: [3,64]\\\"\\n );\\n\\n inputDS.inputDriveSize = (1 << _inputLog2Size);\\n\\n // input box gets initialized with one empty input\\n // so that the L2 DApp knows it's own address\\n inputDS.addInternalInput(\\\"\\\");\\n }\\n\\n /// @notice initialize the Validator Manager facet\\n /// @param _validators initial validator set\\n function initValidatorManager(address payable[] memory _validators)\\n private\\n {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n uint256 maxNumValidators = _validators.length;\\n\\n require(maxNumValidators <= 8, \\\"up to 8 validators\\\");\\n\\n validatorManagerDS.validators = _validators;\\n validatorManagerDS.maxNumValidators = maxNumValidators;\\n\\n // create a new ClaimsMask, with only the consensus goal set,\\n // according to the number of validators\\n validatorManagerDS.claimsMask = LibClaimsMask\\n .newClaimsMaskWithConsensusGoalSet(maxNumValidators);\\n }\\n\\n /// @notice rollups contract initialized\\n /// @param inputDuration duration of input accumulation phase in seconds\\n /// @param challengePeriod duration of challenge period in seconds\\n event RollupsInitialized(uint256 inputDuration, uint256 challengePeriod);\\n\\n /// @notice initialize the Rollups facet\\n /// @param _templateHash state hash of the cartesi machine at t0\\n /// @param _inputDuration duration of input accumulation phase in seconds\\n /// @param _challengePeriod duration of challenge period in seconds\\n function initRollups(\\n bytes32 _templateHash,\\n uint256 _inputDuration,\\n uint256 _challengePeriod\\n ) private {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n rollupsDS.templateHash = _templateHash;\\n rollupsDS.inputDuration = uint32(_inputDuration);\\n rollupsDS.challengePeriod = uint32(_challengePeriod);\\n rollupsDS.inputAccumulationStart = uint32(block.timestamp);\\n rollupsDS.currentPhase_int = uint32(Phase.InputAccumulation);\\n\\n emit RollupsInitialized(_inputDuration, _challengePeriod);\\n }\\n\\n /// @notice FeeManagerImpl contract initialized\\n /// @param feePerClaim fee per claim to reward the validators\\n /// @param feeManagerBank fee manager bank address\\n /// @param feeManagerOwner fee manager owner address\\n event FeeManagerInitialized(\\n uint256 feePerClaim,\\n address feeManagerBank,\\n address feeManagerOwner\\n );\\n\\n /// @notice initalize the Fee Manager facet\\n /// @param _feePerClaim fee per claim to reward the validators\\n /// @param _feeManagerBank fee manager bank address\\n /// @param _feeManagerOwner fee manager owner address\\n function initFeeManager(\\n uint256 _feePerClaim,\\n address _feeManagerBank,\\n address _feeManagerOwner\\n ) private {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n\\n feeManagerDS.feePerClaim = _feePerClaim;\\n feeManagerDS.bank = IBank(_feeManagerBank);\\n feeManagerDS.owner = _feeManagerOwner;\\n\\n emit FeeManagerInitialized(\\n _feePerClaim,\\n _feeManagerBank,\\n _feeManagerOwner\\n );\\n }\\n}\\n\",\"keccak256\":\"0xe627b754df9ee7265f1031cc946bb27d1de8dbb29a7e745453682420b5d9ee76\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610ab1806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063af52770114610030575b600080fd5b61004361003e3660046108d6565b610045565b005b6101267fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f6020527f699d9daa71b280d05a152715774afa0a81a312594b2d731d6b0b2552b7d6f69f8054600160ff1991821681179092557ff97e938d8af42f52387bb74b8b526fda8f184cc2aa534340a8d75a88fbecc77580548216831790557f65d510a5d8f7ef134ec444f7f34ee808c8eeb5177cdfd16be0c40fe1ab43369580548216831790556307f5828d60e41b6000527f5622121b47b8cd0120c4efe45dd5483242f54a3d49bd7679be565d47694918c380549091169091179055565b61016d61013660e0830183610912565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506101be92505050565b610181813560208301356040840135610260565b6101ae608082013561019960c0840160a08501610963565b6101a960e0850160c08601610963565b610339565b6101bb8160600135610407565b50565b80517f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc90600881111561022d5760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b60448201526064015b60405180910390fd5b8251610242906001840190602086019061085c565b5060028201819055610253816104ae565b8260030181905550505050565b7fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c8381557fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189d805463ffffffff8481166401000000000267ffffffffffffffff19909216868216179190911773ffffffff00000000ffffffff0000000000000000191642909116600160401b0263ffffffff60801b191617905560408051848152602081018490527fd6f5a5cd17f05cf9045751ee10f662f62e569c9371ffec8380510aabe63012d391015b60405180910390a150505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc748390557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7580546001600160a01b038481166001600160a01b031992831681179093557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7380549185169190921681178255604080518781526020810194909452830152907f5b54873359173c3d639e39928ad34e113039ce7c799d500e57f8a2c703adb4779060600161032b565b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6003821080159061043a575060408211155b6104865760405162461bcd60e51b815260206004820152601960248201527f4c6f67206f6620696e7075742073697a653a205b332c36345d000000000000006044820152606401610224565b6001821b60028201556040805160208101909152600081526104a990829061050f565b505050565b600060088211156104f65760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b6044820152606401610224565b6000610505600180851b6109b8565b60f01b9392505050565b600061051c838330610523565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561059d5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610224565b6105a6816106c8565b156105b4576105b48561079b565b600085600301546000146105cb57856001016105cd565b855b905060006105da836107ba565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161067f91906109b8565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516106b3939291906109cf565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156106f0576106f061098c565b600184015490915063ffffffff600160401b820481169116600083600281111561071c5761071c61098c565b148015610731575061072e8183610a3b565b42115b15610790576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161077d91610a53565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156107ac5760006107af565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156108265761082661098c565b9050600081600281111561083c5761083c61098c565b146108515761084c826001610a3b565b610853565b815b95945050505050565b8280548282559060005260206000209081019282156108b1579160200282015b828111156108b157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061087c565b506108bd9291506108c1565b5090565b5b808211156108bd57600081556001016108c2565b6000602082840312156108e857600080fd5b813567ffffffffffffffff8111156108ff57600080fd5b8201610100818503121561051c57600080fd5b6000808335601e1984360301811261092957600080fd5b83018035915067ffffffffffffffff82111561094457600080fd5b6020019150600581901b360382131561095c57600080fd5b9250929050565b60006020828403121561097557600080fd5b81356001600160a01b038116811461051c57600080fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156109ca576109ca6109a2565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610a11578581018301518582016080015282016109f5565b81811115610a23576000608083870101525b50601f01601f19169290920160800195945050505050565b60008219821115610a4e57610a4e6109a2565b500190565b6020810160038310610a7557634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212205c1aea48b8585467b96c762ebc1e8162451390f82e4d8071d25e6dfba85f22bb64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063af52770114610030575b600080fd5b61004361003e3660046108d6565b610045565b005b6101267fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f6020527f699d9daa71b280d05a152715774afa0a81a312594b2d731d6b0b2552b7d6f69f8054600160ff1991821681179092557ff97e938d8af42f52387bb74b8b526fda8f184cc2aa534340a8d75a88fbecc77580548216831790557f65d510a5d8f7ef134ec444f7f34ee808c8eeb5177cdfd16be0c40fe1ab43369580548216831790556307f5828d60e41b6000527f5622121b47b8cd0120c4efe45dd5483242f54a3d49bd7679be565d47694918c380549091169091179055565b61016d61013660e0830183610912565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506101be92505050565b610181813560208301356040840135610260565b6101ae608082013561019960c0840160a08501610963565b6101a960e0850160c08601610963565b610339565b6101bb8160600135610407565b50565b80517f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc90600881111561022d5760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b60448201526064015b60405180910390fd5b8251610242906001840190602086019061085c565b5060028201819055610253816104ae565b8260030181905550505050565b7fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c8381557fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189d805463ffffffff8481166401000000000267ffffffffffffffff19909216868216179190911773ffffffff00000000ffffffff0000000000000000191642909116600160401b0263ffffffff60801b191617905560408051848152602081018490527fd6f5a5cd17f05cf9045751ee10f662f62e569c9371ffec8380510aabe63012d391015b60405180910390a150505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc748390557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7580546001600160a01b038481166001600160a01b031992831681179093557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7380549185169190921681178255604080518781526020810194909452830152907f5b54873359173c3d639e39928ad34e113039ce7c799d500e57f8a2c703adb4779060600161032b565b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6003821080159061043a575060408211155b6104865760405162461bcd60e51b815260206004820152601960248201527f4c6f67206f6620696e7075742073697a653a205b332c36345d000000000000006044820152606401610224565b6001821b60028201556040805160208101909152600081526104a990829061050f565b505050565b600060088211156104f65760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b6044820152606401610224565b6000610505600180851b6109b8565b60f01b9392505050565b600061051c838330610523565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561059d5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610224565b6105a6816106c8565b156105b4576105b48561079b565b600085600301546000146105cb57856001016105cd565b855b905060006105da836107ba565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161067f91906109b8565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516106b3939291906109cf565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156106f0576106f061098c565b600184015490915063ffffffff600160401b820481169116600083600281111561071c5761071c61098c565b148015610731575061072e8183610a3b565b42115b15610790576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161077d91610a53565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156107ac5760006107af565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156108265761082661098c565b9050600081600281111561083c5761083c61098c565b146108515761084c826001610a3b565b610853565b815b95945050505050565b8280548282559060005260206000209081019282156108b1579160200282015b828111156108b157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061087c565b506108bd9291506108c1565b5090565b5b808211156108bd57600081556001016108c2565b6000602082840312156108e857600080fd5b813567ffffffffffffffff8111156108ff57600080fd5b8201610100818503121561051c57600080fd5b6000808335601e1984360301811261092957600080fd5b83018035915067ffffffffffffffff82111561094457600080fd5b6020019150600581901b360382131561095c57600080fd5b9250929050565b60006020828403121561097557600080fd5b81356001600160a01b038116811461051c57600080fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156109ca576109ca6109a2565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610a11578581018301518582016080015282016109f5565b81811115610a23576000608083870101525b50601f01601f19169290920160800195945050505050565b60008219821115610a4e57610a4e6109a2565b500190565b6020810160038310610a7557634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212205c1aea48b8585467b96c762ebc1e8162451390f82e4d8071d25e6dfba85f22bb64736f6c634300080d0033", + "libraries": { + "LibClaimsMask": "0x9A676e781A523b5d0C0e43731313A708CB607508" + }, + "devdoc": { + "events": { + "FeeManagerInitialized(uint256,address,address)": { + "params": { + "feeManagerBank": "fee manager bank address", + "feeManagerOwner": "fee manager owner address", + "feePerClaim": "fee per claim to reward the validators" + } + }, + "RollupsInitialized(uint256,uint256)": { + "params": { + "challengePeriod": "duration of challenge period in seconds", + "inputDuration": "duration of input accumulation phase in seconds" + } + } + }, + "kind": "dev", + "methods": { + "init((bytes32,uint256,uint256,uint256,uint256,address,address,address[]))": { + "params": { + "_dConfig": "diamond configurations" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FeeManagerInitialized(uint256,address,address)": { + "notice": "FeeManagerImpl contract initialized" + }, + "RollupsInitialized(uint256,uint256)": { + "notice": "rollups contract initialized" + } + }, + "kind": "user", + "methods": { + "init((bytes32,uint256,uint256,uint256,uint256,address,address,address[]))": { + "notice": "initialize the diamond" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/DiamondLoupeFacet.json b/echo-js/deployments/localhost/DiamondLoupeFacet.json new file mode 100644 index 00000000..9f06b2da --- /dev/null +++ b/echo-js/deployments/localhost/DiamondLoupeFacet.json @@ -0,0 +1,177 @@ +{ + "address": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x3c71f7831330670d9ba13bc3ac8fa0e1809abd4d535b07d16a34c505a62176ed", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", + "transactionIndex": 0, + "gasUsed": "669250", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xbc8e3fd943c16680aa8c7c0d600b556b2101cc5eeaf1357b77900454236748de", + "transactionHash": "0x3c71f7831330670d9ba13bc3ac8fa0e1809abd4d535b07d16a34c505a62176ed", + "logs": [], + "blockNumber": 13, + "cumulativeGasUsed": "669250", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"The selectors associated with a facet address.\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors supported by a specific facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {IDiamondLoupe} from \\\"../interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new Facet[](ds.selectorCount);\\n uint8[] memory numFacetSelectors = new uint8[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_ The selectors associated with a facet address.\\n function facetFunctionSelectors(address _facet)\\n external\\n view\\n override\\n returns (bytes4[] memory facetFunctionSelectors_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n facetFunctionSelectors_ = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n facetFunctionSelectors_[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(facetFunctionSelectors_, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector)\\n external\\n view\\n override\\n returns (address facetAddress_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n }\\n\\n // This implements ERC-165.\\n function supportsInterface(bytes4 _interfaceId)\\n external\\n view\\n override\\n returns (bool)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n return ds.supportedInterfaces[_interfaceId];\\n }\\n}\\n\",\"keccak256\":\"0x4d5563813ef6f3a67df8a4350e17e46cdd8c12686a5be976e1e5b7bd24aa0e59\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\\n}\\n\",\"keccak256\":\"0x6a3129be1f39b6fec871f2c94bf7debf2d6a4e665547a4d83e7f2def38359e44\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(address _facet)\\n external\\n view\\n returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector)\\n external\\n view\\n returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd6c3796a7c45baea6e47fdd5f2cec95d7796991bc9a949604f99875590962a67\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] diamondCut,\\n address init,\\n bytes callData\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x740ea3845282f09bb822e66a189ed431ac799ab08184de7457ef53799b2e99d6\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610b24806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806301ffc9a71461005c57806352ef6b2c146100bd5780637a0ed627146100d2578063adfca15e146100e7578063cdffacc614610107575b600080fd5b6100a861006a3660046108d8565b6001600160e01b03191660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f602052604090205460ff1690565b60405190151581526020015b60405180910390f35b6100c5610159565b6040516100b49190610909565b6100da61031d565b6040516100b4919061099b565b6100fa6100f5366004610a18565b610766565b6040516100b49190610a41565b6101416101153660046108d8565b6001600160e01b0319166000908152600080516020610acf833981519152602052604090205460601c90565b6040516001600160a01b0390911681526020016100b4565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff8111156101aa576101aa610a54565b6040519080825280602002602001820160405280156101d3578160200160208202803683370190505b50915060008060005b600284015461ffff16821015610315576000818152600185016020526040812054905b6008811015610300578361021281610a80565b600288015490955061ffff168511905061030057600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156102a3578a818151811061026857610268610a99565b60200260200101516001600160a01b0316836001600160a01b03160361029157600191506102a3565b8061029b81610a80565b91505061024e565b5080156102b2575050506102ee565b818a89815181106102c5576102c5610a99565b6001600160a01b0390921660209283029190910190910152876102e781610a80565b9850505050505b806102f881610a80565b9150506101ff565b5050808061030d90610a80565b9150506101dc565b505082525090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff81111561036e5761036e610a54565b6040519080825280602002602001820160405280156103b457816020015b60408051808201909152600081526060602082015281526020019060019003908161038c5790505b50600282015490925060009061ffff1667ffffffffffffffff8111156103dc576103dc610a54565b604051908082528060200260200182016040528015610405578160200160208202803683370190505b50905060008060005b600285015461ffff168210156106f4576000818152600186016020526040812054905b60088110156106df578361044481610a80565b600289015490955061ffff16851190506106df57600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b8881101561059d57826001600160a01b03168c82815181106104a4576104a4610a99565b6020026020010151600001516001600160a01b03160361058b57838c82815181106104d1576104d1610a99565b6020026020010151602001518b83815181106104ef576104ef610a99565b602002602001015160ff168151811061050a5761050a610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061054057610540610a99565b602002602001015160ff161061055557600080fd5b89818151811061056757610567610a99565b60200260200101805180919061057c90610aaf565b60ff169052506001915061059d565b8061059581610a80565b915050610480565b5080156105ac575050506106cd565b818b89815181106105bf576105bf610a99565b60209081029190910101516001600160a01b03909116905260028a015461ffff1667ffffffffffffffff8111156105f8576105f8610a54565b604051908082528060200260200182016040528015610621578160200160208202803683370190505b508b898151811061063457610634610a99565b602002602001015160200181905250828b898151811061065657610656610a99565b60200260200101516020015160008151811061067457610674610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106106aa576106aa610a99565b60ff90921660209283029190910190910152876106c681610a80565b9850505050505b806106d781610a80565b915050610431565b505080806106ec90610a80565b91505061040e565b5060005b8281101561075b57600084828151811061071457610714610a99565b602002602001015160ff169050600087838151811061073557610735610a99565b60200260200101516020015190508181525050808061075390610a80565b9150506106f8565b508185525050505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529060009061ffff1667ffffffffffffffff8111156107ba576107ba610a54565b6040519080825280602002602001820160405280156107e3578160200160208202803683370190505b5092506000805b600284015461ffff168210156108ce576000818152600185016020526040812054905b60088110156108b9578361082081610a80565b600288015490955061ffff16851190506108b957600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a168190036108a4578189888151811061087d5761087d610a99565b6001600160e01b031990921660209283029190910190910152866108a081610a80565b9750505b505080806108b190610a80565b91505061080d565b505080806108c690610a80565b9150506107ea565b5050825250919050565b6000602082840312156108ea57600080fd5b81356001600160e01b03198116811461090257600080fd5b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561094a5783516001600160a01b031683529284019291840191600101610925565b50909695505050505050565b600081518084526020808501945080840160005b838110156109905781516001600160e01b0319168752958201959082019060010161096a565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015610a0a57888303603f19018552815180516001600160a01b031684528701518784018790526109f787850182610956565b95880195935050908601906001016109c2565b509098975050505050505050565b600060208284031215610a2a57600080fd5b81356001600160a01b038116811461090257600080fd5b6020815260006109026020830184610956565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610a9257610a92610a6a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103610ac557610ac5610a6a565b6001019291505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131ca264697066735822122086a06e4bb376ef3991d7ba70ce00fa4b43cfacb8059c9980f3c1c386a38ed77b64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806301ffc9a71461005c57806352ef6b2c146100bd5780637a0ed627146100d2578063adfca15e146100e7578063cdffacc614610107575b600080fd5b6100a861006a3660046108d8565b6001600160e01b03191660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f602052604090205460ff1690565b60405190151581526020015b60405180910390f35b6100c5610159565b6040516100b49190610909565b6100da61031d565b6040516100b4919061099b565b6100fa6100f5366004610a18565b610766565b6040516100b49190610a41565b6101416101153660046108d8565b6001600160e01b0319166000908152600080516020610acf833981519152602052604090205460601c90565b6040516001600160a01b0390911681526020016100b4565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff8111156101aa576101aa610a54565b6040519080825280602002602001820160405280156101d3578160200160208202803683370190505b50915060008060005b600284015461ffff16821015610315576000818152600185016020526040812054905b6008811015610300578361021281610a80565b600288015490955061ffff168511905061030057600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156102a3578a818151811061026857610268610a99565b60200260200101516001600160a01b0316836001600160a01b03160361029157600191506102a3565b8061029b81610a80565b91505061024e565b5080156102b2575050506102ee565b818a89815181106102c5576102c5610a99565b6001600160a01b0390921660209283029190910190910152876102e781610a80565b9850505050505b806102f881610a80565b9150506101ff565b5050808061030d90610a80565b9150506101dc565b505082525090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff81111561036e5761036e610a54565b6040519080825280602002602001820160405280156103b457816020015b60408051808201909152600081526060602082015281526020019060019003908161038c5790505b50600282015490925060009061ffff1667ffffffffffffffff8111156103dc576103dc610a54565b604051908082528060200260200182016040528015610405578160200160208202803683370190505b50905060008060005b600285015461ffff168210156106f4576000818152600186016020526040812054905b60088110156106df578361044481610a80565b600289015490955061ffff16851190506106df57600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b8881101561059d57826001600160a01b03168c82815181106104a4576104a4610a99565b6020026020010151600001516001600160a01b03160361058b57838c82815181106104d1576104d1610a99565b6020026020010151602001518b83815181106104ef576104ef610a99565b602002602001015160ff168151811061050a5761050a610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061054057610540610a99565b602002602001015160ff161061055557600080fd5b89818151811061056757610567610a99565b60200260200101805180919061057c90610aaf565b60ff169052506001915061059d565b8061059581610a80565b915050610480565b5080156105ac575050506106cd565b818b89815181106105bf576105bf610a99565b60209081029190910101516001600160a01b03909116905260028a015461ffff1667ffffffffffffffff8111156105f8576105f8610a54565b604051908082528060200260200182016040528015610621578160200160208202803683370190505b508b898151811061063457610634610a99565b602002602001015160200181905250828b898151811061065657610656610a99565b60200260200101516020015160008151811061067457610674610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106106aa576106aa610a99565b60ff90921660209283029190910190910152876106c681610a80565b9850505050505b806106d781610a80565b915050610431565b505080806106ec90610a80565b91505061040e565b5060005b8281101561075b57600084828151811061071457610714610a99565b602002602001015160ff169050600087838151811061073557610735610a99565b60200260200101516020015190508181525050808061075390610a80565b9150506106f8565b508185525050505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529060009061ffff1667ffffffffffffffff8111156107ba576107ba610a54565b6040519080825280602002602001820160405280156107e3578160200160208202803683370190505b5092506000805b600284015461ffff168210156108ce576000818152600185016020526040812054905b60088110156108b9578361082081610a80565b600288015490955061ffff16851190506108b957600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a168190036108a4578189888151811061087d5761087d610a99565b6001600160e01b031990921660209283029190910190910152866108a081610a80565b9750505b505080806108b190610a80565b91505061080d565b505080806108c690610a80565b9150506107ea565b5050825250919050565b6000602082840312156108ea57600080fd5b81356001600160e01b03198116811461090257600080fd5b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561094a5783516001600160a01b031683529284019291840191600101610925565b50909695505050505050565b600081518084526020808501945080840160005b838110156109905781516001600160e01b0319168752958201959082019060010161096a565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015610a0a57888303603f19018552815180516001600160a01b031684528701518784018790526109f787850182610956565b95880195935050908601906001016109c2565b509098975050505050505050565b600060208284031215610a2a57600080fd5b81356001600160a01b038116811461090257600080fd5b6020815260006109026020830184610956565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610a9257610a92610a6a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103610ac557610ac5610a6a565b6001019291505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131ca264697066735822122086a06e4bb376ef3991d7ba70ce00fa4b43cfacb8059c9980f3c1c386a38ed77b64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "The selectors associated with a facet address." + } + }, + "facets()": { + "returns": { + "facets_": "Facet" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors supported by a specific facet." + }, + "facets()": { + "notice": "Gets all facets and their selectors." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/ERC20PortalFacet.json b/echo-js/deployments/localhost/ERC20PortalFacet.json new file mode 100644 index 00000000..666905e6 --- /dev/null +++ b/echo-js/deployments/localhost/ERC20PortalFacet.json @@ -0,0 +1,121 @@ +{ + "address": "0x59b670e9fA9D0A427751Af201D676719a970857b", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "ERC20", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "ERC20Deposited", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_ERC20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "erc20Deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x1effcf7afd0dc630ee782e48cb2b730f02214c59da2db79b5558cf50249a88d0", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x59b670e9fA9D0A427751Af201D676719a970857b", + "transactionIndex": 0, + "gasUsed": "479906", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2a8665409aefab35b129928bef7be8a23247709fb6947d8411b5b2219925812f", + "transactionHash": "0x1effcf7afd0dc630ee782e48cb2b730f02214c59da2db79b5558cf50249a88d0", + "logs": [], + "blockNumber": 22, + "cumulativeGasUsed": "479906", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"ERC20\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"ERC20Deposited\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ERC20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"erc20Deposit\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"erc20Deposit(address,uint256,bytes)\":{\"params\":{\"_ERC20\":\"address of the ERC20 token contract\",\"_amount\":\"amount of the ERC20 token to be deposited\",\"_data\":\"information to be interpreted by L2\"},\"returns\":{\"_0\":\"hash of input generated by deposit\"}}},\"version\":1},\"userdoc\":{\"events\":{\"ERC20Deposited(address,address,uint256,bytes)\":{\"notice\":\"emitted on ERC20 deposited\"}},\"kind\":\"user\",\"methods\":{\"erc20Deposit(address,uint256,bytes)\":{\"notice\":\"deposit an amount of a generic ERC20 in the portal and create tokens in L2\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/ERC20PortalFacet.sol\":\"ERC20PortalFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/ERC20PortalFacet.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Generic ERC20 Portal facet\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport {IERC20Portal} from \\\"../interfaces/IERC20Portal.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\n\\ncontract ERC20PortalFacet is IERC20Portal {\\n using LibInput for LibInput.DiamondStorage;\\n\\n bytes32 constant INPUT_HEADER = keccak256(\\\"ERC20_Transfer\\\");\\n\\n /// @notice deposit an amount of a generic ERC20 in the portal and create tokens in L2\\n /// @param _ERC20 address of the ERC20 token contract\\n /// @param _amount amount of the ERC20 token to be deposited\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function erc20Deposit(\\n address _ERC20,\\n uint256 _amount,\\n bytes calldata _data\\n ) public override returns (bytes32) {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n IERC20 token = IERC20(_ERC20);\\n\\n require(\\n token.transferFrom(msg.sender, address(this), _amount),\\n \\\"ERC20 transferFrom failed\\\"\\n );\\n\\n bytes memory input = abi.encode(\\n INPUT_HEADER,\\n msg.sender,\\n _ERC20,\\n _amount,\\n _data\\n );\\n\\n emit ERC20Deposited(_ERC20, msg.sender, _amount, _data);\\n return inputDS.addInternalInput(input);\\n }\\n}\\n\",\"keccak256\":\"0x30d5d1aad8854d02b7783c1b07812bc8a637d64c2dcf43638aeb7c62de47ed3a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IERC20Portal.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Generic ERC20 Portal interface\\npragma solidity >=0.7.0;\\n\\ninterface IERC20Portal {\\n /// @notice deposit an amount of a generic ERC20 token in the portal and create tokens in L2\\n /// @param _ERC20 address of the ERC20 token contract\\n /// @param _amount amount of the ERC20 token to be deposited\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function erc20Deposit(\\n address _ERC20,\\n uint256 _amount,\\n bytes calldata _data\\n ) external returns (bytes32);\\n\\n /// @notice emitted on ERC20 deposited\\n event ERC20Deposited(\\n address ERC20,\\n address sender,\\n uint256 amount,\\n bytes data\\n );\\n}\\n\",\"keccak256\":\"0xc252480d20774dc9d6bdb0f632e364f4232d3be447db5a45f86ae1c904adacc6\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063cb1061a614610030575b600080fd5b61004361003e36600461053b565b610055565b60405190815260200160405180910390f35b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6040516323b872dd60e01b81523360048201523060248201526044810187905290915086906001600160a01b038216906323b872dd906064016020604051808303816000875af11580156100d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f591906105d0565b6101465760405162461bcd60e51b815260206004820152601960248201527f4552433230207472616e7366657246726f6d206661696c65640000000000000060448201526064015b60405180910390fd5b60007f59da2a984e165ae4487c99e5d1dca7e04c8a99301be6bc092932cb5d7f03437833898989896040516020016101839695949392919061061b565b60405160208183030381529060405290507f29e6a9ed1b00933e0de5679ea9bc6ad323969a70b69b627425b46ac0431c7b0188338989896040516101cb959493929190610655565b60405180910390a16101dd83826101e9565b98975050505050505050565b60006101f68383306101fd565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156102775760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640161013d565b610280816103a2565b1561028e5761028e8561047a565b600085600301546000146102a557856001016102a7565b855b905060006102b483610499565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161035991906106aa565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161038d939291906106c1565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103ca576103ca61072d565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156103fb576103fb61072d565b148015610410575061040d8183610743565b42115b1561046f576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161045c9161075b565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561048b57600061048e565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105055761050561072d565b9050600081600281111561051b5761051b61072d565b146105305761052b826001610743565b610532565b815b95945050505050565b6000806000806060858703121561055157600080fd5b84356001600160a01b038116811461056857600080fd5b935060208501359250604085013567ffffffffffffffff8082111561058c57600080fd5b818701915087601f8301126105a057600080fd5b8135818111156105af57600080fd5b8860208285010111156105c157600080fd5b95989497505060200194505050565b6000602082840312156105e257600080fd5b815180151581146101f657600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8681526001600160a01b038681166020830152851660408201526060810184905260a0608082018190526000906101dd90830184866105f2565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061068990830184866105f2565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156106bc576106bc610694565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610703578581018301518582016080015282016106e7565b81811115610715576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b6000821982111561075657610756610694565b500190565b602081016003831061077d57634e487b7160e01b600052602160045260246000fd5b9190529056fea264697066735822122085f1f711a938addfee9fe400008e8e390be52bc8e586f1c69e748d85d44bc31064736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063cb1061a614610030575b600080fd5b61004361003e36600461053b565b610055565b60405190815260200160405180910390f35b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6040516323b872dd60e01b81523360048201523060248201526044810187905290915086906001600160a01b038216906323b872dd906064016020604051808303816000875af11580156100d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f591906105d0565b6101465760405162461bcd60e51b815260206004820152601960248201527f4552433230207472616e7366657246726f6d206661696c65640000000000000060448201526064015b60405180910390fd5b60007f59da2a984e165ae4487c99e5d1dca7e04c8a99301be6bc092932cb5d7f03437833898989896040516020016101839695949392919061061b565b60405160208183030381529060405290507f29e6a9ed1b00933e0de5679ea9bc6ad323969a70b69b627425b46ac0431c7b0188338989896040516101cb959493929190610655565b60405180910390a16101dd83826101e9565b98975050505050505050565b60006101f68383306101fd565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156102775760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640161013d565b610280816103a2565b1561028e5761028e8561047a565b600085600301546000146102a557856001016102a7565b855b905060006102b483610499565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161035991906106aa565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161038d939291906106c1565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103ca576103ca61072d565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156103fb576103fb61072d565b148015610410575061040d8183610743565b42115b1561046f576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161045c9161075b565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561048b57600061048e565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105055761050561072d565b9050600081600281111561051b5761051b61072d565b146105305761052b826001610743565b610532565b815b95945050505050565b6000806000806060858703121561055157600080fd5b84356001600160a01b038116811461056857600080fd5b935060208501359250604085013567ffffffffffffffff8082111561058c57600080fd5b818701915087601f8301126105a057600080fd5b8135818111156105af57600080fd5b8860208285010111156105c157600080fd5b95989497505060200194505050565b6000602082840312156105e257600080fd5b815180151581146101f657600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8681526001600160a01b038681166020830152851660408201526060810184905260a0608082018190526000906101dd90830184866105f2565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061068990830184866105f2565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156106bc576106bc610694565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610703578581018301518582016080015282016106e7565b81811115610715576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b6000821982111561075657610756610694565b500190565b602081016003831061077d57634e487b7160e01b600052602160045260246000fd5b9190529056fea264697066735822122085f1f711a938addfee9fe400008e8e390be52bc8e586f1c69e748d85d44bc31064736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "erc20Deposit(address,uint256,bytes)": { + "params": { + "_ERC20": "address of the ERC20 token contract", + "_amount": "amount of the ERC20 token to be deposited", + "_data": "information to be interpreted by L2" + }, + "returns": { + "_0": "hash of input generated by deposit" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "ERC20Deposited(address,address,uint256,bytes)": { + "notice": "emitted on ERC20 deposited" + } + }, + "kind": "user", + "methods": { + "erc20Deposit(address,uint256,bytes)": { + "notice": "deposit an amount of a generic ERC20 in the portal and create tokens in L2" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/ERC721PortalFacet.json b/echo-js/deployments/localhost/ERC721PortalFacet.json new file mode 100644 index 00000000..ab0cb0ea --- /dev/null +++ b/echo-js/deployments/localhost/ERC721PortalFacet.json @@ -0,0 +1,190 @@ +{ + "address": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "ERC721", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "ERC721Received", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "ERC721", + "type": "address" + }, + { + "indexed": false, + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721Withdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "erc721Withdrawal", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x37a6600202a16cb710e7bfde0a1796caa589c752db1187989d04ad27dbd4463e", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1", + "transactionIndex": 0, + "gasUsed": "555119", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0d36fc220a283ade63173169ccc5b967a727200a01ee764f2d702f26038848a4", + "transactionHash": "0x37a6600202a16cb710e7bfde0a1796caa589c752db1187989d04ad27dbd4463e", + "logs": [], + "blockNumber": 23, + "cumulativeGasUsed": "555119", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"ERC721\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"ERC721Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"ERC721\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ERC721Withdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"erc721Withdrawal\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"erc721Withdrawal(bytes)\":{\"details\":\"can only be called by the Rollups contract\",\"params\":{\"_data\":\"data with withdrawal information\"}},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"The ERC721 smart contract calls this function on the recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return of other than the magic value MUST result in the transaction being reverted. Note: the contract address is always the message sender.\",\"params\":{\"_data\":\"Additional data to be interpreted by L2\",\"_from\":\"The address which previously owned the token\",\"_operator\":\"The address which called `safeTransferFrom` function\",\"_tokenId\":\"The NFT identifier which is being transferred\"},\"returns\":{\"_0\":\"this function selector unless throwing\"}}},\"version\":1},\"userdoc\":{\"events\":{\"ERC721Received(address,address,address,uint256,bytes)\":{\"notice\":\"emitted on a call to `onERC721Received`\"},\"ERC721Withdrawn(address,address,uint256)\":{\"notice\":\"emitted on ERC721 withdrawal\"}},\"kind\":\"user\",\"methods\":{\"erc721Withdrawal(bytes)\":{\"notice\":\"withdraw an ERC721 token from the portal\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handle the receipt of an NFT\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/ERC721PortalFacet.sol\":\"ERC721PortalFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x0d4de01fe5360c38b4ad2b0822a12722958428f5138a7ff47c1720eb6fa52bba\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/ERC721PortalFacet.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Generic ERC721 Portal facet\\npragma solidity ^0.8.0;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\nimport {IERC721Portal} from \\\"../interfaces/IERC721Portal.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\n\\ncontract ERC721PortalFacet is IERC721Portal {\\n using LibInput for LibInput.DiamondStorage;\\n\\n bytes32 constant INPUT_HEADER = keccak256(\\\"ERC721_Transfer\\\");\\n\\n /// @notice Handle the receipt of an NFT\\n /// @dev The ERC721 smart contract calls this function on the recipient\\n /// after a `transfer`. This function MAY throw to revert and reject the\\n /// transfer. Return of other than the magic value MUST result in the\\n /// transaction being reverted.\\n /// Note: the contract address is always the message sender.\\n /// @param _operator The address which called `safeTransferFrom` function\\n /// @param _from The address which previously owned the token\\n /// @param _tokenId The NFT identifier which is being transferred\\n /// @param _data Additional data to be interpreted by L2\\n /// @return this function selector unless throwing\\n function onERC721Received(\\n address _operator,\\n address _from,\\n uint256 _tokenId,\\n bytes calldata _data\\n ) public override returns (bytes4) {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n address erc721Contract = msg.sender;\\n\\n bytes memory input = abi.encode(\\n INPUT_HEADER,\\n erc721Contract,\\n _operator,\\n _from,\\n _tokenId,\\n _data\\n );\\n\\n inputDS.addInternalInput(input);\\n\\n emit ERC721Received(erc721Contract, _operator, _from, _tokenId, _data);\\n\\n // return the magic value to approve the transfer\\n return this.onERC721Received.selector;\\n }\\n\\n /// @notice withdraw an ERC721 token from the portal\\n /// @param _data data with withdrawal information\\n /// @dev can only be called by the Rollups contract\\n function erc721Withdrawal(bytes calldata _data)\\n public\\n override\\n returns (bool)\\n {\\n // Delegate calls preserve msg.sender, msg.value and address(this)\\n require(msg.sender == address(this), \\\"only itself\\\");\\n\\n (address tokenAddr, address payable receiver, uint256 tokenId) = abi\\n .decode(_data, (address, address, uint256));\\n\\n IERC721 token = IERC721(tokenAddr);\\n\\n // transfer reverts on failure\\n token.safeTransferFrom(address(this), receiver, tokenId);\\n\\n emit ERC721Withdrawn(tokenAddr, receiver, tokenId);\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x87ab790c157e34f53ca132c2b1056fea1728a1c67b62abc7fd83ed08c94a84ff\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IERC721Portal.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Generic ERC721 Portal interface\\npragma solidity >=0.7.0;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\ninterface IERC721Portal is IERC721Receiver {\\n /// @notice withdraw an ERC721 token from the portal\\n /// @param _data data with withdrawal information\\n /// @dev can only be called by the Rollups contract\\n function erc721Withdrawal(bytes calldata _data) external returns (bool);\\n\\n /// @notice emitted on a call to `onERC721Received`\\n event ERC721Received(\\n address ERC721,\\n address operator,\\n address sender,\\n uint256 tokenId,\\n bytes data\\n );\\n\\n /// @notice emitted on ERC721 withdrawal\\n event ERC721Withdrawn(\\n address ERC721,\\n address payable receiver,\\n uint256 tokenId\\n );\\n}\\n\",\"keccak256\":\"0x44d396dc8754fbbafd5b7cadf77a1acf13d9dab26ce31effc1d7f32308726ca0\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610915806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063150b7a021461003b57806315e55ce51461006c575b600080fd5b61004e61004936600461063a565b61008f565b6040516001600160e01b031990911681526020015b60405180910390f35b61007f61007a3660046106ad565b610168565b6040519015158152602001610063565b6040516000907f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff90339083906100f5907f64d9de45e7db1c0a7cb7960ad25107a6379b6ab85b30444f3a8d724857c1ac789084908c908c908c908c908c90602001610718565b60408051601f1981840301815291905290506101118382610287565b507f33dcfebf3eaf42764314a95335af55bb1c008027c47c827e6e09119071639e1d828a8a8a8a8a60405161014b96959493929190610767565b60405180910390a150630a85bd0160e11b98975050505050505050565b60003330146101ac5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080806101bc858701876107af565b604051632142170760e11b81523060048201526001600160a01b03808416602483015260448201839052939650919450925084918216906342842e0e90606401600060405180830381600087803b15801561021657600080fd5b505af115801561022a573d6000803e3d6000fd5b5050604080516001600160a01b038089168252871660208201529081018590527feea167c0d54572a80626f5fd092a7c1f7b5d8e309533747e7e7d77b0558d6cf19250606001905060405180910390a15060019695505050505050565b600061029483833061029b565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156103155760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d000000000000000060448201526064016101a3565b61031e81610440565b1561032c5761032c85610518565b600085600301546000146103435785600101610345565b855b9050600061035283610537565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f79190610806565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161042b9392919061081d565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff16600281111561046857610468610889565b600184015490915063ffffffff68010000000000000000820481169116600083600281111561049957610499610889565b1480156104ae57506104ab818361089f565b42115b1561050d576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104fa916108b7565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561052957600061052c565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105a3576105a3610889565b905060008160028111156105b9576105b9610889565b146105ce576105c982600161089f565b6105d0565b815b95945050505050565b6001600160a01b03811681146105ee57600080fd5b50565b60008083601f84011261060357600080fd5b50813567ffffffffffffffff81111561061b57600080fd5b60208301915083602082850101111561063357600080fd5b9250929050565b60008060008060006080868803121561065257600080fd5b853561065d816105d9565b9450602086013561066d816105d9565b935060408601359250606086013567ffffffffffffffff81111561069057600080fd5b61069c888289016105f1565b969995985093965092949392505050565b600080602083850312156106c057600080fd5b823567ffffffffffffffff8111156106d757600080fd5b6106e3858286016105f1565b90969095509350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b0387811660208301528681166040830152851660608201526080810184905260c060a0820181905260009061075a90830184866106ef565b9998505050505050505050565b6001600160a01b0387811682528681166020830152851660408201526060810184905260a0608082018190526000906107a390830184866106ef565b98975050505050505050565b6000806000606084860312156107c457600080fd5b83356107cf816105d9565b925060208401356107df816105d9565b929592945050506040919091013590565b634e487b7160e01b600052601160045260246000fd5b600082821015610818576108186107f0565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561085f57858101830151858201608001528201610843565b81811115610871576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156108b2576108b26107f0565b500190565b60208101600383106108d957634e487b7160e01b600052602160045260246000fd5b9190529056fea264697066735822122063bd39ba5fcde318ac6f9113d8c4f5275c6487653824db8e78a5e0a317694cac64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063150b7a021461003b57806315e55ce51461006c575b600080fd5b61004e61004936600461063a565b61008f565b6040516001600160e01b031990911681526020015b60405180910390f35b61007f61007a3660046106ad565b610168565b6040519015158152602001610063565b6040516000907f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff90339083906100f5907f64d9de45e7db1c0a7cb7960ad25107a6379b6ab85b30444f3a8d724857c1ac789084908c908c908c908c908c90602001610718565b60408051601f1981840301815291905290506101118382610287565b507f33dcfebf3eaf42764314a95335af55bb1c008027c47c827e6e09119071639e1d828a8a8a8a8a60405161014b96959493929190610767565b60405180910390a150630a85bd0160e11b98975050505050505050565b60003330146101ac5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080806101bc858701876107af565b604051632142170760e11b81523060048201526001600160a01b03808416602483015260448201839052939650919450925084918216906342842e0e90606401600060405180830381600087803b15801561021657600080fd5b505af115801561022a573d6000803e3d6000fd5b5050604080516001600160a01b038089168252871660208201529081018590527feea167c0d54572a80626f5fd092a7c1f7b5d8e309533747e7e7d77b0558d6cf19250606001905060405180910390a15060019695505050505050565b600061029483833061029b565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156103155760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d000000000000000060448201526064016101a3565b61031e81610440565b1561032c5761032c85610518565b600085600301546000146103435785600101610345565b855b9050600061035283610537565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f79190610806565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161042b9392919061081d565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff16600281111561046857610468610889565b600184015490915063ffffffff68010000000000000000820481169116600083600281111561049957610499610889565b1480156104ae57506104ab818361089f565b42115b1561050d576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104fa916108b7565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561052957600061052c565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105a3576105a3610889565b905060008160028111156105b9576105b9610889565b146105ce576105c982600161089f565b6105d0565b815b95945050505050565b6001600160a01b03811681146105ee57600080fd5b50565b60008083601f84011261060357600080fd5b50813567ffffffffffffffff81111561061b57600080fd5b60208301915083602082850101111561063357600080fd5b9250929050565b60008060008060006080868803121561065257600080fd5b853561065d816105d9565b9450602086013561066d816105d9565b935060408601359250606086013567ffffffffffffffff81111561069057600080fd5b61069c888289016105f1565b969995985093965092949392505050565b600080602083850312156106c057600080fd5b823567ffffffffffffffff8111156106d757600080fd5b6106e3858286016105f1565b90969095509350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b0387811660208301528681166040830152851660608201526080810184905260c060a0820181905260009061075a90830184866106ef565b9998505050505050505050565b6001600160a01b0387811682528681166020830152851660408201526060810184905260a0608082018190526000906107a390830184866106ef565b98975050505050505050565b6000806000606084860312156107c457600080fd5b83356107cf816105d9565b925060208401356107df816105d9565b929592945050506040919091013590565b634e487b7160e01b600052601160045260246000fd5b600082821015610818576108186107f0565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561085f57858101830151858201608001528201610843565b81811115610871576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156108b2576108b26107f0565b500190565b60208101600383106108d957634e487b7160e01b600052602160045260246000fd5b9190529056fea264697066735822122063bd39ba5fcde318ac6f9113d8c4f5275c6487653824db8e78a5e0a317694cac64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "erc721Withdrawal(bytes)": { + "details": "can only be called by the Rollups contract", + "params": { + "_data": "data with withdrawal information" + } + }, + "onERC721Received(address,address,uint256,bytes)": { + "details": "The ERC721 smart contract calls this function on the recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return of other than the magic value MUST result in the transaction being reverted. Note: the contract address is always the message sender.", + "params": { + "_data": "Additional data to be interpreted by L2", + "_from": "The address which previously owned the token", + "_operator": "The address which called `safeTransferFrom` function", + "_tokenId": "The NFT identifier which is being transferred" + }, + "returns": { + "_0": "this function selector unless throwing" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "ERC721Received(address,address,address,uint256,bytes)": { + "notice": "emitted on a call to `onERC721Received`" + }, + "ERC721Withdrawn(address,address,uint256)": { + "notice": "emitted on ERC721 withdrawal" + } + }, + "kind": "user", + "methods": { + "erc721Withdrawal(bytes)": { + "notice": "withdraw an ERC721 token from the portal" + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handle the receipt of an NFT" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/EtherPortalFacet.json b/echo-js/deployments/localhost/EtherPortalFacet.json new file mode 100644 index 00000000..b3ee8ade --- /dev/null +++ b/echo-js/deployments/localhost/EtherPortalFacet.json @@ -0,0 +1,153 @@ +{ + "address": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "EtherDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EtherWithdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "etherDeposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "etherWithdrawal", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x427ad7f8d928e9d19034cc848dc4c8f0f92f363607ab511903f7590c0c854657", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44", + "transactionIndex": 0, + "gasUsed": "506127", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc08e7d786a345088cb0e24a89c9110a1abd3d939f29e2c3afc3b81b3d3c40623", + "transactionHash": "0x427ad7f8d928e9d19034cc848dc4c8f0f92f363607ab511903f7590c0c854657", + "logs": [], + "blockNumber": 24, + "cumulativeGasUsed": "506127", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"EtherDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EtherWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"etherDeposit\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"etherWithdrawal\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"etherDeposit(bytes)\":{\"params\":{\"_data\":\"information to be interpreted by L2\"},\"returns\":{\"_0\":\"hash of input generated by deposit\"}},\"etherWithdrawal(bytes)\":{\"details\":\"can only be called by the Rollups contract\",\"params\":{\"_data\":\"data with withdrawal information\"}}},\"version\":1},\"userdoc\":{\"events\":{\"EtherDeposited(address,uint256,bytes)\":{\"notice\":\"emitted on Ether deposited\"},\"EtherWithdrawn(address,uint256)\":{\"notice\":\"emitted on Ether withdrawal\"}},\"kind\":\"user\",\"methods\":{\"etherDeposit(bytes)\":{\"notice\":\"deposit an amount of Ether in the portal and create Ether in L2\"},\"etherWithdrawal(bytes)\":{\"notice\":\"withdraw an amount of Ether from the portal\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/EtherPortalFacet.sol\":\"EtherPortalFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/EtherPortalFacet.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Ether Portal facet\\npragma solidity ^0.8.0;\\n\\nimport {IEtherPortal} from \\\"../interfaces/IEtherPortal.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\n\\ncontract EtherPortalFacet is IEtherPortal {\\n using LibInput for LibInput.DiamondStorage;\\n\\n bytes32 constant INPUT_HEADER = keccak256(\\\"Ether_Transfer\\\");\\n\\n /// @notice deposit an amount of Ether in the portal and create Ether in L2\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function etherDeposit(bytes calldata _data)\\n public\\n payable\\n override\\n returns (bytes32)\\n {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n bytes memory input = abi.encode(\\n INPUT_HEADER,\\n msg.sender,\\n msg.value,\\n _data\\n );\\n\\n emit EtherDeposited(msg.sender, msg.value, _data);\\n return inputDS.addInternalInput(input);\\n }\\n\\n /// @notice withdraw an amount of Ether from the portal\\n /// @param _data data with withdrawal information\\n /// @dev can only be called by the Rollups contract\\n function etherWithdrawal(bytes calldata _data)\\n public\\n override\\n returns (bool)\\n {\\n // Delegate calls preserve msg.sender, msg.value and address(this)\\n require(msg.sender == address(this), \\\"only itself\\\");\\n\\n (address payable receiver, uint256 value) = abi.decode(\\n _data,\\n (address, uint256)\\n );\\n\\n // We used to call receiver.transfer(value) but it's no\\n // longer considered safe, as it assumes gas costs are\\n // immutable, while in fact they are not.\\n (bool success, ) = receiver.call{value: value}(\\\"\\\");\\n require(success, \\\"transfer failed\\\");\\n\\n emit EtherWithdrawn(receiver, value);\\n\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xff3ceab5676d1e626aed77ebcad60da7b3bdf8109badb672407ea500b48338dd\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IEtherPortal.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Ether Portal interface\\npragma solidity >=0.7.0;\\n\\ninterface IEtherPortal {\\n /// @notice deposit an amount of Ether in the portal and create Ether in L2\\n /// @param _data information to be interpreted by L2\\n /// @return hash of input generated by deposit\\n function etherDeposit(bytes calldata _data)\\n external\\n payable\\n returns (bytes32);\\n\\n /// @notice withdraw an amount of Ether from the portal\\n /// @param _data data with withdrawal information\\n /// @dev can only be called by the Rollups contract\\n function etherWithdrawal(bytes calldata _data) external returns (bool);\\n\\n /// @notice emitted on Ether deposited\\n event EtherDeposited(address sender, uint256 amount, bytes data);\\n\\n /// @notice emitted on Ether withdrawal\\n event EtherWithdrawn(address payable receiver, uint256 amount);\\n}\\n\",\"keccak256\":\"0xe4cf1f9c0036627a992efdbc1cb73a871e0c3208e07a5d1580b64af29e16f0f9\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610832806100206000396000f3fe6080604052600436106100295760003560e01c80632abfe7b31461002e57806374956b9414610054575b600080fd5b61004161003c3660046105cf565b610084565b6040519081526020015b60405180910390f35b34801561006057600080fd5b5061007461006f3660046105cf565b610146565b604051901515815260200161004b565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905060007ff258e0fc39d35abd7d8393dcfe7e1cf8c745ddca38ae41d451d0c55ac5f2c4ce333487876040516020016100e595949392919061066a565b60405160208183030381529060405290507fa9888e32d8ea552aaeb3018b9c85c77c66ecc61cf8d1989f9e3271a88205ee633334878760405161012b94939291906106a3565b60405180910390a161013d8282610280565b95945050505050565b600033301461018a5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080610199848601866106d5565b915091506000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146101ea576040519150601f19603f3d011682016040523d82523d6000602084013e6101ef565b606091505b50509050806102325760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610181565b604080516001600160a01b0385168152602081018490527f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c910160405180910390a150600195945050505050565b600061028d838330610294565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561030e5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610181565b61031781610439565b156103255761032585610511565b6000856003015460001461033c578560010161033e565b855b9050600061034b83610530565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f09190610723565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516104249392919061073a565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff166002811115610461576104616107a6565b600184015490915063ffffffff680100000000000000008204811691166000836002811115610492576104926107a6565b1480156104a757506104a481836107bc565b42115b15610506576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104f3916107d4565b60405180910390a1506001949350505050565b506000949350505050565b600381015415610522576000610525565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561059c5761059c6107a6565b905060008160028111156105b2576105b26107a6565b146105c7576105c28260016107bc565b61013d565b509392505050565b600080602083850312156105e257600080fd5b823567ffffffffffffffff808211156105fa57600080fd5b818501915085601f83011261060e57600080fd5b81358181111561061d57600080fd5b86602082850101111561062f57600080fd5b60209290920196919550909350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b85815260018060a01b0385166020820152836040820152608060608201526000610698608083018486610641565b979650505050505050565b60018060a01b03851681528360208201526060604082015260006106cb606083018486610641565b9695505050505050565b600080604083850312156106e857600080fd5b82356001600160a01b03811681146106ff57600080fd5b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156107355761073561070d565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561077c57858101830151858201608001528201610760565b8181111561078e576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156107cf576107cf61070d565b500190565b60208101600383106107f657634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212205f8b8b334540ae8474e8ed820a158d5c1603d75d34c78a0a7fdce1a205004e7864736f6c634300080d0033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80632abfe7b31461002e57806374956b9414610054575b600080fd5b61004161003c3660046105cf565b610084565b6040519081526020015b60405180910390f35b34801561006057600080fd5b5061007461006f3660046105cf565b610146565b604051901515815260200161004b565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905060007ff258e0fc39d35abd7d8393dcfe7e1cf8c745ddca38ae41d451d0c55ac5f2c4ce333487876040516020016100e595949392919061066a565b60405160208183030381529060405290507fa9888e32d8ea552aaeb3018b9c85c77c66ecc61cf8d1989f9e3271a88205ee633334878760405161012b94939291906106a3565b60405180910390a161013d8282610280565b95945050505050565b600033301461018a5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080610199848601866106d5565b915091506000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146101ea576040519150601f19603f3d011682016040523d82523d6000602084013e6101ef565b606091505b50509050806102325760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610181565b604080516001600160a01b0385168152602081018490527f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c910160405180910390a150600195945050505050565b600061028d838330610294565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561030e5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610181565b61031781610439565b156103255761032585610511565b6000856003015460001461033c578560010161033e565b855b9050600061034b83610530565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f09190610723565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516104249392919061073a565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff166002811115610461576104616107a6565b600184015490915063ffffffff680100000000000000008204811691166000836002811115610492576104926107a6565b1480156104a757506104a481836107bc565b42115b15610506576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104f3916107d4565b60405180910390a1506001949350505050565b506000949350505050565b600381015415610522576000610525565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561059c5761059c6107a6565b905060008160028111156105b2576105b26107a6565b146105c7576105c28260016107bc565b61013d565b509392505050565b600080602083850312156105e257600080fd5b823567ffffffffffffffff808211156105fa57600080fd5b818501915085601f83011261060e57600080fd5b81358181111561061d57600080fd5b86602082850101111561062f57600080fd5b60209290920196919550909350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b85815260018060a01b0385166020820152836040820152608060608201526000610698608083018486610641565b979650505050505050565b60018060a01b03851681528360208201526060604082015260006106cb606083018486610641565b9695505050505050565b600080604083850312156106e857600080fd5b82356001600160a01b03811681146106ff57600080fd5b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156107355761073561070d565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561077c57858101830151858201608001528201610760565b8181111561078e576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156107cf576107cf61070d565b500190565b60208101600383106107f657634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212205f8b8b334540ae8474e8ed820a158d5c1603d75d34c78a0a7fdce1a205004e7864736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "etherDeposit(bytes)": { + "params": { + "_data": "information to be interpreted by L2" + }, + "returns": { + "_0": "hash of input generated by deposit" + } + }, + "etherWithdrawal(bytes)": { + "details": "can only be called by the Rollups contract", + "params": { + "_data": "data with withdrawal information" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "EtherDeposited(address,uint256,bytes)": { + "notice": "emitted on Ether deposited" + }, + "EtherWithdrawn(address,uint256)": { + "notice": "emitted on Ether withdrawal" + } + }, + "kind": "user", + "methods": { + "etherDeposit(bytes)": { + "notice": "deposit an amount of Ether in the portal and create Ether in L2" + }, + "etherWithdrawal(bytes)": { + "notice": "withdraw an amount of Ether from the portal" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/FeeManagerFacet.json b/echo-js/deployments/localhost/FeeManagerFacet.json new file mode 100644 index 00000000..dbaae0df --- /dev/null +++ b/echo-js/deployments/localhost/FeeManagerFacet.json @@ -0,0 +1,198 @@ +{ + "address": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "FeePerClaimReset", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "validator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claims", + "type": "uint256" + } + ], + "name": "FeeRedeemed", + "type": "event" + }, + { + "inputs": [], + "name": "getFeeManagerBank", + "outputs": [ + { + "internalType": "contract IBank", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "getNumClaimsRedeemed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "numClaimsRedeemable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + } + ], + "name": "redeemFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "resetFeePerClaim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xaa9e28a7bf6c6fc245c381176ae8dfd6c0ab95e755f5977dbed23df6ed68d366", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f", + "transactionIndex": 0, + "gasUsed": "626660", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd6347f28406e977146397249e7371ed27291f716f2ec1a7ae18eb9a678ad10f1", + "transactionHash": "0xaa9e28a7bf6c6fc245c381176ae8dfd6c0ab95e755f5977dbed23df6ed68d366", + "logs": [], + "blockNumber": 25, + "cumulativeGasUsed": "626660", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"FeePerClaimReset\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"claims\",\"type\":\"uint256\"}],\"name\":\"FeeRedeemed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getFeeManagerBank\",\"outputs\":[{\"internalType\":\"contract IBank\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"getNumClaimsRedeemed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"numClaimsRedeemable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"redeemFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"resetFeePerClaim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getNumClaimsRedeemed(address)\":{\"params\":{\"_validator\":\"address of the validator\"}},\"numClaimsRedeemable(address)\":{\"params\":{\"_validator\":\"address of the validator\"}},\"redeemFee(address)\":{\"params\":{\"_validator\":\"address of the validator that is redeeming\"}},\"resetFeePerClaim(uint256)\":{\"params\":{\"_value\":\"the new value of fee per claim\"}}},\"version\":1},\"userdoc\":{\"events\":{\"FeePerClaimReset(uint256)\":{\"notice\":\"emitted on resetting feePerClaim\"},\"FeeRedeemed(address,uint256)\":{\"notice\":\"emitted on ERC20 funds redeemed by validator\"}},\"kind\":\"user\",\"methods\":{\"getFeeManagerBank()\":{\"notice\":\"returns the bank used to manage fees\"},\"getNumClaimsRedeemed(address)\":{\"notice\":\"this function can be called to check the number of claims that has been redeemed for the validator\"},\"numClaimsRedeemable(address)\":{\"notice\":\"this function can be called to check the number of claims that's redeemable for the validator\"},\"redeemFee(address)\":{\"notice\":\"this function can be called to redeem fees for validators\"},\"resetFeePerClaim(uint256)\":{\"notice\":\"contract owner can reset the value of fee per claim\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/FeeManagerFacet.sol\":\"FeeManagerFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/FeeManagerFacet.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager facet\\npragma solidity >=0.8.8;\\n\\nimport {IBank} from \\\"../IBank.sol\\\";\\nimport {IFeeManager} from \\\"../interfaces/IFeeManager.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\ncontract FeeManagerFacet is IFeeManager {\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n /// @notice functions modified by noReentrancy are not subject to recursion\\n modifier noReentrancy() {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n require(!feeManagerDS.lock, \\\"reentrancy not allowed\\\");\\n feeManagerDS.lock = true;\\n _;\\n feeManagerDS.lock = false;\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(address _validator)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n return feeManagerDS.numClaimsRedeemable(_validator);\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(address _validator)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n return feeManagerDS.getNumClaimsRedeemed(_validator);\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(uint256 _value) public override {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n feeManagerDS.onlyOwner();\\n feeManagerDS.resetFeePerClaim(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(address _validator) public override noReentrancy {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n feeManagerDS.redeemFee(_validator);\\n }\\n\\n /// @notice returns the bank used to manage fees\\n function getFeeManagerBank() public view override returns (IBank) {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n return feeManagerDS.bank;\\n }\\n}\\n\",\"keccak256\":\"0xbc7705a8ec363654d6ade4275214a58eb02ac5374421be18f5a5826a11c3e50f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager interface\\npragma solidity >=0.7.0;\\n\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\ninterface IFeeManager {\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(address _validator)\\n external\\n view\\n returns (uint256);\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(address _validator)\\n external\\n view\\n returns (uint256);\\n\\n /// @notice contract owner can set/reset the value of fee per claim\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(uint256 _value) external;\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(address _validator) external;\\n\\n /// @notice returns the bank used to manage fees\\n function getFeeManagerBank() external view returns (IBank);\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0x7f55753293a46fb0d6a1fa822b27ea38157d1b6ebd3f20fa4273894a251aea4d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610a61806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80636e964cea1461005c5780637a5bf67c1461009b578063a859b983146100b0578063de7a8d11146100d1578063e8f56171146100e4575b600080fd5b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75546040516001600160a01b0390911681526020015b60405180910390f35b6100ae6100a93660046108ea565b6100f7565b005b6100c36100be366004610903565b61011d565b604051908152602001610092565b6100ae6100df366004610903565b61013f565b6100c36100f2366004610903565b610210565b600080516020610a0c83398151915261010f8161022b565b6101198183610287565b5050565b6000600080516020610a0c8339815191526101388184610418565b9392505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7554600080516020610a0c83398151915290600160a01b900460ff16156101c65760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff60a01b1916600160a01b17905560006101f2600080516020610a0c83398151915290565b90506101fe81846104ac565b50600201805460ff60a01b1916905550565b6000600080516020610a0c83398151915261013881846105fc565b80546001600160a01b031633146102845760405162461bcd60e51b815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060448201526064016101bd565b50565b6000805160206109ec83398151915260005b81600201548110156103d85760008260010182815481106102bc576102bc61092c565b6000918252602090912001546001600160a01b0316905080156103c55760006102e586836105fc565b905080156103c35760038601546102fd9084836106b6565b600387015560018601546000906103149083610958565b600288015460405163bec3fa1760e01b81526001600160a01b0386811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b5050604080516001600160a01b0387168152602081018690527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505b505b50806103d081610977565b915050610299565b50600183018290556040518281527fd454bae44ce74e91cf62780bdb9278052c00cfd79c13003d5761b400475b12f69060200160405180910390a1505050565b60006001600160a01b03821661046a5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006104858285610709565b905060006104a08287600301546107e890919063ffffffff16565b93505050505b92915050565b60006104b883836105fc565b9050600081116105025760405162461bcd60e51b81526020600482015260156024820152741b9bdd1a1a5b99c81d1bc81c995919595b481e595d605a1b60448201526064016101bd565b6000805160206109ec833981519152600061051d8285610709565b60038601549091506105309082856106b6565b600386015560018501546000906105479085610958565b600287015460405163bec3fa1760e01b81526001600160a01b0388811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561059957600080fd5b505af11580156105ad573d6000803e3d6000fd5b5050604080516001600160a01b0389168152602081018890527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505050505050565b60006001600160a01b03821661064e5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006106698285610709565b905060006106848284600301546107e890919063ffffffff16565b9050600061069f8388600301546107e890919063ffffffff16565b90506106ab8183610990565b979650505050505050565b6000600883106106d85760405162461bcd60e51b81526004016101bd906109a7565b60006106e485856107e8565b905060006106f284836109d3565b90506106ff868683610836565b9695505050505050565b60006001600160a01b03821661074d5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064016101bd565b60005b60018401548110156107a9578360010181815481106107715761077161092c565b6000918252602090912001546001600160a01b03908116908416036107975790506104a6565b806107a181610977565b915050610750565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b60448201526064016101bd565b60006008821061080a5760405162461bcd60e51b81526004016101bd906109a7565b600061081b60016340000000610990565b90508061082984601e610958565b85901c1691505092915050565b6000600883106108585760405162461bcd60e51b81526004016101bd906109a7565b61086760016340000000610990565b8211156108ac5760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b60448201526064016101bd565b60006108b984601e610958565b6108c860016340000000610990565b901b1990508481166108db85601e610958565b9390931b909217949350505050565b6000602082840312156108fc57600080fd5b5035919050565b60006020828403121561091557600080fd5b81356001600160a01b038116811461013857600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561097257610972610942565b500290565b60006001820161098957610989610942565b5060010190565b6000828210156109a2576109a2610942565b500390565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b600082198211156109e6576109e6610942565b50019056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73a2646970667358221220bbef9ee9631eea87502ee3148d59871e6852c0024e2669ce3d9053cce53809ef64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c80636e964cea1461005c5780637a5bf67c1461009b578063a859b983146100b0578063de7a8d11146100d1578063e8f56171146100e4575b600080fd5b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75546040516001600160a01b0390911681526020015b60405180910390f35b6100ae6100a93660046108ea565b6100f7565b005b6100c36100be366004610903565b61011d565b604051908152602001610092565b6100ae6100df366004610903565b61013f565b6100c36100f2366004610903565b610210565b600080516020610a0c83398151915261010f8161022b565b6101198183610287565b5050565b6000600080516020610a0c8339815191526101388184610418565b9392505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7554600080516020610a0c83398151915290600160a01b900460ff16156101c65760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff60a01b1916600160a01b17905560006101f2600080516020610a0c83398151915290565b90506101fe81846104ac565b50600201805460ff60a01b1916905550565b6000600080516020610a0c83398151915261013881846105fc565b80546001600160a01b031633146102845760405162461bcd60e51b815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060448201526064016101bd565b50565b6000805160206109ec83398151915260005b81600201548110156103d85760008260010182815481106102bc576102bc61092c565b6000918252602090912001546001600160a01b0316905080156103c55760006102e586836105fc565b905080156103c35760038601546102fd9084836106b6565b600387015560018601546000906103149083610958565b600288015460405163bec3fa1760e01b81526001600160a01b0386811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b5050604080516001600160a01b0387168152602081018690527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505b505b50806103d081610977565b915050610299565b50600183018290556040518281527fd454bae44ce74e91cf62780bdb9278052c00cfd79c13003d5761b400475b12f69060200160405180910390a1505050565b60006001600160a01b03821661046a5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006104858285610709565b905060006104a08287600301546107e890919063ffffffff16565b93505050505b92915050565b60006104b883836105fc565b9050600081116105025760405162461bcd60e51b81526020600482015260156024820152741b9bdd1a1a5b99c81d1bc81c995919595b481e595d605a1b60448201526064016101bd565b6000805160206109ec833981519152600061051d8285610709565b60038601549091506105309082856106b6565b600386015560018501546000906105479085610958565b600287015460405163bec3fa1760e01b81526001600160a01b0388811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561059957600080fd5b505af11580156105ad573d6000803e3d6000fd5b5050604080516001600160a01b0389168152602081018890527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505050505050565b60006001600160a01b03821661064e5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006106698285610709565b905060006106848284600301546107e890919063ffffffff16565b9050600061069f8388600301546107e890919063ffffffff16565b90506106ab8183610990565b979650505050505050565b6000600883106106d85760405162461bcd60e51b81526004016101bd906109a7565b60006106e485856107e8565b905060006106f284836109d3565b90506106ff868683610836565b9695505050505050565b60006001600160a01b03821661074d5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064016101bd565b60005b60018401548110156107a9578360010181815481106107715761077161092c565b6000918252602090912001546001600160a01b03908116908416036107975790506104a6565b806107a181610977565b915050610750565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b60448201526064016101bd565b60006008821061080a5760405162461bcd60e51b81526004016101bd906109a7565b600061081b60016340000000610990565b90508061082984601e610958565b85901c1691505092915050565b6000600883106108585760405162461bcd60e51b81526004016101bd906109a7565b61086760016340000000610990565b8211156108ac5760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b60448201526064016101bd565b60006108b984601e610958565b6108c860016340000000610990565b901b1990508481166108db85601e610958565b9390931b909217949350505050565b6000602082840312156108fc57600080fd5b5035919050565b60006020828403121561091557600080fd5b81356001600160a01b038116811461013857600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561097257610972610942565b500290565b60006001820161098957610989610942565b5060010190565b6000828210156109a2576109a2610942565b500390565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b600082198211156109e6576109e6610942565b50019056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73a2646970667358221220bbef9ee9631eea87502ee3148d59871e6852c0024e2669ce3d9053cce53809ef64736f6c634300080d0033", + "libraries": { + "LibClaimsMask": "0x9A676e781A523b5d0C0e43731313A708CB607508" + }, + "devdoc": { + "kind": "dev", + "methods": { + "getNumClaimsRedeemed(address)": { + "params": { + "_validator": "address of the validator" + } + }, + "numClaimsRedeemable(address)": { + "params": { + "_validator": "address of the validator" + } + }, + "redeemFee(address)": { + "params": { + "_validator": "address of the validator that is redeeming" + } + }, + "resetFeePerClaim(uint256)": { + "params": { + "_value": "the new value of fee per claim" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FeePerClaimReset(uint256)": { + "notice": "emitted on resetting feePerClaim" + }, + "FeeRedeemed(address,uint256)": { + "notice": "emitted on ERC20 funds redeemed by validator" + } + }, + "kind": "user", + "methods": { + "getFeeManagerBank()": { + "notice": "returns the bank used to manage fees" + }, + "getNumClaimsRedeemed(address)": { + "notice": "this function can be called to check the number of claims that has been redeemed for the validator" + }, + "numClaimsRedeemable(address)": { + "notice": "this function can be called to check the number of claims that's redeemable for the validator" + }, + "redeemFee(address)": { + "notice": "this function can be called to redeem fees for validators" + }, + "resetFeePerClaim(uint256)": { + "notice": "contract owner can reset the value of fee per claim" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/InputFacet.json b/echo-js/deployments/localhost/InputFacet.json new file mode 100644 index 00000000..02446d89 --- /dev/null +++ b/echo-js/deployments/localhost/InputFacet.json @@ -0,0 +1,187 @@ +{ + "address": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "inputIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "name": "InputAdded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_input", + "type": "bytes" + } + ], + "name": "addInput", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentInbox", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getInput", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNumberOfInputs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xaac585869d90c2be534b71ca8f187c2dd9bd6c464d90ba567dee8aae9a4d53c0", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x4A679253410272dd5232B3Ff7cF5dbB88f295319", + "transactionIndex": 0, + "gasUsed": "444643", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe6382d2f82b6a44352951345dab24b34e27f7e266a1de143186a19bc078cf60c", + "transactionHash": "0xaac585869d90c2be534b71ca8f187c2dd9bd6c464d90ba567dee8aae9a4d53c0", + "logs": [], + "blockNumber": 26, + "cumulativeGasUsed": "444643", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epochNumber\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"inputIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"InputAdded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_input\",\"type\":\"bytes\"}],\"name\":\"addInput\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentInbox\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getInput\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumberOfInputs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addInput(bytes)\":{\"details\":\"offchain code is responsible for making sure that input size is power of 2 and multiple of 8 since\",\"params\":{\"_input\":\"input to be understood by offchain machine\"}},\"getCurrentInbox()\":{\"returns\":{\"_0\":\"input inbox currently receiveing inputs\"}},\"getInput(uint256)\":{\"details\":\"currentInputBox being zero means that the inputs for the claimed epoch are on input box one\",\"params\":{\"_index\":\"index of input inside that inbox\"},\"returns\":{\"_0\":\"hash of input at index _index\"}},\"getNumberOfInputs()\":{\"details\":\"currentInputBox being zero means that the inputs for the claimed epoch are on input box one\",\"returns\":{\"_0\":\"number of inputs on that input box\"}}},\"version\":1},\"userdoc\":{\"events\":{\"InputAdded(uint256,uint256,address,uint256,bytes)\":{\"notice\":\"input added\"}},\"kind\":\"user\",\"methods\":{\"addInput(bytes)\":{\"notice\":\"add input to processed by next epoch\"},\"getCurrentInbox()\":{\"notice\":\"get inbox currently receiveing inputs\"},\"getInput(uint256)\":{\"notice\":\"get input inside inbox of currently proposed claim\"},\"getNumberOfInputs()\":{\"notice\":\"get number of inputs inside inbox of currently proposed claim\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/InputFacet.sol\":\"InputFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/InputFacet.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input facet\\npragma solidity ^0.8.0;\\n\\nimport {IInput} from \\\"../interfaces/IInput.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\n\\ncontract InputFacet is IInput {\\n using LibInput for LibInput.DiamondStorage;\\n\\n /// @notice add input to processed by next epoch\\n /// @param _input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n // the offchain machine has a 8 byte word\\n function addInput(bytes calldata _input) public override returns (bytes32) {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n return inputDS.addInput(_input);\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param _index index of input inside that inbox\\n /// @return hash of input at index _index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(uint256 _index) public view override returns (bytes32) {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n return inputDS.getInput(_index);\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs() public view override returns (uint256) {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n return inputDS.getNumberOfInputs();\\n }\\n\\n /// @notice get inbox currently receiveing inputs\\n /// @return input inbox currently receiveing inputs\\n function getCurrentInbox() public view override returns (uint256) {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n return inputDS.currentInputBox;\\n }\\n}\\n\",\"keccak256\":\"0xe7355e94250381c1d3f4ed399ff5db753a7909296b8b9bf7437e965bcd704793\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input interface\\npragma solidity >=0.7.0;\\n\\ninterface IInput {\\n /// @notice adds input to correct inbox\\n /// @param _input bytes array of input\\n /// @return merkle root hash of input\\n /// @dev msg.sender and timestamp are preppended log2 size\\n /// has to be calculated offchain taking that into account\\n function addInput(bytes calldata _input) external returns (bytes32);\\n\\n /// @notice returns input from correct input inbox\\n /// @param _index position of the input on inbox\\n /// @return root hash of input\\n function getInput(uint256 _index) external view returns (bytes32);\\n\\n /// @notice returns number of inputs on correct inbox\\n /// @return number of inputs of non active inbox\\n function getNumberOfInputs() external view returns (uint256);\\n\\n /// @notice returns active current inbox index\\n /// @return index of current active inbox\\n function getCurrentInbox() external view returns (uint256);\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0xecfc3bb2987598d5b5020c345cef7d570f757de69223d7cb16500c4d5fdd429d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610716806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80631ab6dcab14610051578063a459600e14610086578063e795524414610099578063f32078e8146100a1575b600080fd5b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a688224991302545b60405190815260200160405180910390f35b610074610094366004610550565b6100b4565b6100746100e8565b6100746100af366004610569565b61011a565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6100e1818461018a565b9392505050565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff610114816101e4565b91505090565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905061018284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506102059050565b949350505050565b600082600301546000146101bd578260000182815481106101ad576101ad6105db565b90600052602060002001546100e1565b8260010182815481106101d2576101d26105db565b90600052602060002001549392505050565b600081600301546000146101f95781546101ff565b60018201545b92915050565b60006100e18383336000807fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c905084600201548451111561028c5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640160405180910390fd5b610295816103b7565b156102a3576102a38561048f565b600085600301546000146102ba57856001016102bc565b855b905060006102c9836104ae565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161036e9190610607565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516103a29392919061061e565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103df576103df61068a565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156104105761041061068a565b148015610425575061042281836106a0565b42115b15610484576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f91610471916106b8565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156104a05760006104a3565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561051a5761051a61068a565b905060008160028111156105305761053061068a565b14610545576105408260016106a0565b610547565b815b95945050505050565b60006020828403121561056257600080fd5b5035919050565b6000806020838503121561057c57600080fd5b823567ffffffffffffffff8082111561059457600080fd5b818501915085601f8301126105a857600080fd5b8135818111156105b757600080fd5b8660208285010111156105c957600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610619576106196105f1565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561066057858101830151858201608001528201610644565b81811115610672576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156106b3576106b36105f1565b500190565b60208101600383106106da57634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212208d2585ea14781006c7c2a1c4cd31794f4afd52d508e1dfb6b383bee26039dbca64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80631ab6dcab14610051578063a459600e14610086578063e795524414610099578063f32078e8146100a1575b600080fd5b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a688224991302545b60405190815260200160405180910390f35b610074610094366004610550565b6100b4565b6100746100e8565b6100746100af366004610569565b61011a565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6100e1818461018a565b9392505050565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff610114816101e4565b91505090565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905061018284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506102059050565b949350505050565b600082600301546000146101bd578260000182815481106101ad576101ad6105db565b90600052602060002001546100e1565b8260010182815481106101d2576101d26105db565b90600052602060002001549392505050565b600081600301546000146101f95781546101ff565b60018201545b92915050565b60006100e18383336000807fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c905084600201548451111561028c5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640160405180910390fd5b610295816103b7565b156102a3576102a38561048f565b600085600301546000146102ba57856001016102bc565b855b905060006102c9836104ae565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161036e9190610607565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516103a29392919061061e565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103df576103df61068a565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156104105761041061068a565b148015610425575061042281836106a0565b42115b15610484576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f91610471916106b8565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156104a05760006104a3565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561051a5761051a61068a565b905060008160028111156105305761053061068a565b14610545576105408260016106a0565b610547565b815b95945050505050565b60006020828403121561056257600080fd5b5035919050565b6000806020838503121561057c57600080fd5b823567ffffffffffffffff8082111561059457600080fd5b818501915085601f8301126105a857600080fd5b8135818111156105b757600080fd5b8660208285010111156105c957600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610619576106196105f1565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561066057858101830151858201608001528201610644565b81811115610672576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156106b3576106b36105f1565b500190565b60208101600383106106da57634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212208d2585ea14781006c7c2a1c4cd31794f4afd52d508e1dfb6b383bee26039dbca64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "addInput(bytes)": { + "details": "offchain code is responsible for making sure that input size is power of 2 and multiple of 8 since", + "params": { + "_input": "input to be understood by offchain machine" + } + }, + "getCurrentInbox()": { + "returns": { + "_0": "input inbox currently receiveing inputs" + } + }, + "getInput(uint256)": { + "details": "currentInputBox being zero means that the inputs for the claimed epoch are on input box one", + "params": { + "_index": "index of input inside that inbox" + }, + "returns": { + "_0": "hash of input at index _index" + } + }, + "getNumberOfInputs()": { + "details": "currentInputBox being zero means that the inputs for the claimed epoch are on input box one", + "returns": { + "_0": "number of inputs on that input box" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "InputAdded(uint256,uint256,address,uint256,bytes)": { + "notice": "input added" + } + }, + "kind": "user", + "methods": { + "addInput(bytes)": { + "notice": "add input to processed by next epoch" + }, + "getCurrentInbox()": { + "notice": "get inbox currently receiveing inputs" + }, + "getInput(uint256)": { + "notice": "get input inside inbox of currently proposed claim" + }, + "getNumberOfInputs()": { + "notice": "get number of inputs inside inbox of currently proposed claim" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibClaimsMask.json b/echo-js/deployments/localhost/LibClaimsMask.json new file mode 100644 index 00000000..40ebee78 --- /dev/null +++ b/echo-js/deployments/localhost/LibClaimsMask.json @@ -0,0 +1,40 @@ +{ + "address": "0x9A676e781A523b5d0C0e43731313A708CB607508", + "abi": [], + "transactionHash": "0x3fd601465ca5a7b7608ae66dd90e54f166d9e7e55dd73611661aa3157fe46dcc", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x9A676e781A523b5d0C0e43731313A708CB607508", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8a12b1c673fdd7b953a49eb4be83652e7ded715d8b83fd0062e90ecce4e8a221", + "transactionHash": "0x3fd601465ca5a7b7608ae66dd90e54f166d9e7e55dd73611661aa3157fe46dcc", + "logs": [], + "blockNumber": 15, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibClaimsMask.sol\":\"LibClaimsMask\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f207a18bf0f032f65f6fc0ed17c44444682051896bbf2631ca031feb8e936f1c64736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f207a18bf0f032f65f6fc0ed17c44444682051896bbf2631ca031feb8e936f1c64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibDiamond.json b/echo-js/deployments/localhost/LibDiamond.json new file mode 100644 index 00000000..6fa10de5 --- /dev/null +++ b/echo-js/deployments/localhost/LibDiamond.json @@ -0,0 +1,102 @@ +{ + "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } + ], + "transactionHash": "0xedc13f0c1ce94653974570525a95f6949e55b0e0a065fe497930079b83dd02a7", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xba253c12cd7b9f0e977df7c65e37f871eef9a1d7ebffa611743ed03bede7819e", + "transactionHash": "0xedc13f0c1ce94653974570525a95f6949e55b0e0a065fe497930079b83dd02a7", + "logs": [], + "blockNumber": 11, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibDiamond.sol\":\"LibDiamond\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\\n}\\n\",\"keccak256\":\"0x6a3129be1f39b6fec871f2c94bf7debf2d6a4e665547a4d83e7f2def38359e44\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] diamondCut,\\n address init,\\n bytes callData\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x740ea3845282f09bb822e66a189ed431ac799ab08184de7457ef53799b2e99d6\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c5a84bf61634d1ec545a6f8b1feb7ca9ae19b6c1de1b62724654313e991082a264736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c5a84bf61634d1ec545a6f8b1feb7ca9ae19b6c1de1b62724654313e991082a264736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibDisputeManager.json b/echo-js/deployments/localhost/LibDisputeManager.json new file mode 100644 index 00000000..9a9ceafa --- /dev/null +++ b/echo-js/deployments/localhost/LibDisputeManager.json @@ -0,0 +1,40 @@ +{ + "address": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed", + "abi": [], + "transactionHash": "0x30f53ee6f9124a2b30e32f3555a7836a13689728ac14d0926b82c9a3c5c751ac", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x122ce6f3bd087572c4d9774136f86fac15d5bc067720eed872731b9022fa9e5a", + "transactionHash": "0x30f53ee6f9124a2b30e32f3555a7836a13689728ac14d0926b82c9a3c5c751ac", + "logs": [], + "blockNumber": 19, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibDisputeManager.sol\":\"LibDisputeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204141febf12e97e090ace242057c841d7f58ca4cd6a3d58622ac11f58772c29d664736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204141febf12e97e090ace242057c841d7f58ca4cd6a3d58622ac11f58772c29d664736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibFeeManager.json b/echo-js/deployments/localhost/LibFeeManager.json new file mode 100644 index 00000000..74f299b8 --- /dev/null +++ b/echo-js/deployments/localhost/LibFeeManager.json @@ -0,0 +1,81 @@ +{ + "address": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "FeePerClaimReset", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "validator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claims", + "type": "uint256" + } + ], + "name": "FeeRedeemed", + "type": "event" + } + ], + "transactionHash": "0x16ea571f922ff165f1c46d49d37ba29b9196b4de23254d09082bb352f82f0179", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x30ec8aff9b1b46e44b66c4e3f5d8aaf17e15d818ba849e307321903a8ef04f46", + "transactionHash": "0x16ea571f922ff165f1c46d49d37ba29b9196b4de23254d09082bb352f82f0179", + "logs": [], + "blockNumber": 20, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"FeePerClaimReset\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"validator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"claims\",\"type\":\"uint256\"}],\"name\":\"FeeRedeemed\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"events\":{\"FeePerClaimReset(uint256)\":{\"notice\":\"emitted on resetting feePerClaim\"},\"FeeRedeemed(address,uint256)\":{\"notice\":\"emitted on ERC20 funds redeemed by validator\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibFeeManager.sol\":\"LibFeeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122038dc250b0eee390254c1a470f46a497aebc692590f944731c1e94ef49b70814964736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122038dc250b0eee390254c1a470f46a497aebc692590f944731c1e94ef49b70814964736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "events": { + "FeePerClaimReset(uint256)": { + "notice": "emitted on resetting feePerClaim" + }, + "FeeRedeemed(address,uint256)": { + "notice": "emitted on ERC20 funds redeemed by validator" + } + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibInput.json b/echo-js/deployments/localhost/LibInput.json new file mode 100644 index 00000000..600ae99a --- /dev/null +++ b/echo-js/deployments/localhost/LibInput.json @@ -0,0 +1,94 @@ +{ + "address": "0x0B306BF915C4d645ff596e518fAf3F9669b97016", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "inputIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "name": "InputAdded", + "type": "event" + } + ], + "transactionHash": "0x8d7a0179a1a89c343cf01b74b4613b8c83fd6225436cf8ee04edec29ea420bf3", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x0B306BF915C4d645ff596e518fAf3F9669b97016", + "transactionIndex": 0, + "gasUsed": "72205", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x19b571eec547f7924d4f624ddc1a38010c914a6c368c57ec070418396d498a79", + "transactionHash": "0x8d7a0179a1a89c343cf01b74b4613b8c83fd6225436cf8ee04edec29ea420bf3", + "logs": [], + "blockNumber": 16, + "cumulativeGasUsed": "72205", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epochNumber\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"inputIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"InputAdded\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"InputAdded(uint256,uint256,address,uint256,bytes)\":{\"params\":{\"epochNumber\":\"which epoch this input belongs to\",\"input\":\"input data\",\"inputIndex\":\"index of the input just added\",\"sender\":\"msg.sender\",\"timestamp\":\"block.timestamp\"}}},\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"events\":{\"InputAdded(uint256,uint256,address,uint256,bytes)\":{\"notice\":\"input added\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibInput.sol\":\"LibInput\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122045af0a00851f115a4bb6fc3594433c2460d8f7c3ab9dc1838829ed264d67d1a064736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122045af0a00851f115a4bb6fc3594433c2460d8f7c3ab9dc1838829ed264d67d1a064736f6c634300080d0033", + "devdoc": { + "events": { + "InputAdded(uint256,uint256,address,uint256,bytes)": { + "params": { + "epochNumber": "which epoch this input belongs to", + "input": "input data", + "inputIndex": "index of the input just added", + "sender": "msg.sender", + "timestamp": "block.timestamp" + } + } + }, + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "events": { + "InputAdded(uint256,uint256,address,uint256,bytes)": { + "notice": "input added" + } + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibOutput.json b/echo-js/deployments/localhost/LibOutput.json new file mode 100644 index 00000000..dd9f5181 --- /dev/null +++ b/echo-js/deployments/localhost/LibOutput.json @@ -0,0 +1,40 @@ +{ + "address": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1", + "abi": [], + "transactionHash": "0xa94802e992eb4780569bf38b9dde82c02bf6f4b88e64c4eb4991d2411f0e3bc6", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x9b5958f1a848c6c85e9ef17545687fbe72e1bce4534c85a8711cd83c04e7d0e0", + "transactionHash": "0xa94802e992eb4780569bf38b9dde82c02bf6f4b88e64c4eb4991d2411f0e3bc6", + "logs": [], + "blockNumber": 17, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibOutput.sol\":\"LibOutput\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b9feb0adc702e3687bbb49b753bbb4f4a9adbe0e872b8403f87aa9130e9c38e764736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b9feb0adc702e3687bbb49b753bbb4f4a9adbe0e872b8403f87aa9130e9c38e764736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibRollups.json b/echo-js/deployments/localhost/LibRollups.json new file mode 100644 index 00000000..73de0c8f --- /dev/null +++ b/echo-js/deployments/localhost/LibRollups.json @@ -0,0 +1,129 @@ +{ + "address": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "epochHash", + "type": "bytes32" + } + ], + "name": "FinalizeEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Phase", + "name": "newPhase", + "type": "uint8" + } + ], + "name": "PhaseChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "loser", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "winningClaim", + "type": "bytes32" + } + ], + "name": "ResolveDispute", + "type": "event" + } + ], + "transactionHash": "0x2866a1def92cee6438340f6409b0550dc0197ea8906397bc7d36ac1065bba3f7", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3f0f5cac6bca9a7a848613ff02b840c81ac7e864716c31fcacec70f274b85818", + "transactionHash": "0x2866a1def92cee6438340f6409b0550dc0197ea8906397bc7d36ac1065bba3f7", + "logs": [], + "blockNumber": 21, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epochNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"epochHash\",\"type\":\"bytes32\"}],\"name\":\"FinalizeEpoch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Phase\",\"name\":\"newPhase\",\"type\":\"uint8\"}],\"name\":\"PhaseChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"loser\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"winningClaim\",\"type\":\"bytes32\"}],\"name\":\"ResolveDispute\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"FinalizeEpoch(uint256,bytes32)\":{\"params\":{\"epochHash\":\"claim being submitted by this epoch\",\"epochNumber\":\"number of the epoch being finalized\"}},\"PhaseChange(uint8)\":{\"params\":{\"newPhase\":\"new phase\"}},\"ResolveDispute(address,address,bytes32)\":{\"params\":{\"loser\":\"loser of dispute\",\"winner\":\"winner of dispute\",\"winningClaim\":\"initial claim of winning validator\"}}},\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"events\":{\"FinalizeEpoch(uint256,bytes32)\":{\"notice\":\"epoch finalized\"},\"PhaseChange(uint8)\":{\"notice\":\"phase change\"},\"ResolveDispute(address,address,bytes32)\":{\"notice\":\"dispute resolved\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibRollups.sol\":\"LibRollups\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205a485fcaa0fe53c20da938a3897cb43d793987fb9c8138b345986de57832228164736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205a485fcaa0fe53c20da938a3897cb43d793987fb9c8138b345986de57832228164736f6c634300080d0033", + "devdoc": { + "events": { + "FinalizeEpoch(uint256,bytes32)": { + "params": { + "epochHash": "claim being submitted by this epoch", + "epochNumber": "number of the epoch being finalized" + } + }, + "PhaseChange(uint8)": { + "params": { + "newPhase": "new phase" + } + }, + "ResolveDispute(address,address,bytes32)": { + "params": { + "loser": "loser of dispute", + "winner": "winner of dispute", + "winningClaim": "initial claim of winning validator" + } + } + }, + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "events": { + "FinalizeEpoch(uint256,bytes32)": { + "notice": "epoch finalized" + }, + "PhaseChange(uint8)": { + "notice": "phase change" + }, + "ResolveDispute(address,address,bytes32)": { + "notice": "dispute resolved" + } + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/LibValidatorManager.json b/echo-js/deployments/localhost/LibValidatorManager.json new file mode 100644 index 00000000..a425b159 --- /dev/null +++ b/echo-js/deployments/localhost/LibValidatorManager.json @@ -0,0 +1,118 @@ +{ + "address": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Result", + "name": "result", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes32[2]", + "name": "claims", + "type": "bytes32[2]" + }, + { + "indexed": false, + "internalType": "address payable[2]", + "name": "validators", + "type": "address[2]" + } + ], + "name": "ClaimReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Result", + "name": "result", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes32[2]", + "name": "claims", + "type": "bytes32[2]" + }, + { + "indexed": false, + "internalType": "address payable[2]", + "name": "validators", + "type": "address[2]" + } + ], + "name": "DisputeEnded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "claim", + "type": "bytes32" + } + ], + "name": "NewEpoch", + "type": "event" + } + ], + "transactionHash": "0x9a65d7dbf5d2d338b74b449d91e1c88f591655c2b1e13a15ddc4cd5858dfcb5e", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE", + "transactionIndex": 0, + "gasUsed": "72217", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xab8e4bd56bb5867ae8be06b3d8c023f8b8743393e945bc9cb9537a09b3d7eb7b", + "transactionHash": "0x9a65d7dbf5d2d338b74b449d91e1c88f591655c2b1e13a15ddc4cd5858dfcb5e", + "logs": [], + "blockNumber": 18, + "cumulativeGasUsed": "72217", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Result\",\"name\":\"result\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32[2]\",\"name\":\"claims\",\"type\":\"bytes32[2]\"},{\"indexed\":false,\"internalType\":\"address payable[2]\",\"name\":\"validators\",\"type\":\"address[2]\"}],\"name\":\"ClaimReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Result\",\"name\":\"result\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32[2]\",\"name\":\"claims\",\"type\":\"bytes32[2]\"},{\"indexed\":false,\"internalType\":\"address payable[2]\",\"name\":\"validators\",\"type\":\"address[2]\"}],\"name\":\"DisputeEnded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"claim\",\"type\":\"bytes32\"}],\"name\":\"NewEpoch\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"events\":{\"ClaimReceived(uint8,bytes32[2],address[2])\":{\"notice\":\"emitted on Claim received\"},\"DisputeEnded(uint8,bytes32[2],address[2])\":{\"notice\":\"emitted on Dispute end\"},\"NewEpoch(bytes32)\":{\"notice\":\"emitted on new Epoch\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/LibValidatorManager.sol\":\"LibValidatorManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122080f3bd59d03023cff2312fd721be2a546ac4e0495a947d7ae9acb2f25034dc9764736f6c634300080d0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122080f3bd59d03023cff2312fd721be2a546ac4e0495a947d7ae9acb2f25034dc9764736f6c634300080d0033", + "libraries": { + "LibClaimsMask": "0x9A676e781A523b5d0C0e43731313A708CB607508" + }, + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "events": { + "ClaimReceived(uint8,bytes32[2],address[2])": { + "notice": "emitted on Claim received" + }, + "DisputeEnded(uint8,bytes32[2],address[2])": { + "notice": "emitted on Dispute end" + }, + "NewEpoch(bytes32)": { + "notice": "emitted on new Epoch" + } + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/Merkle.json b/echo-js/deployments/localhost/Merkle.json new file mode 100644 index 00000000..591c524d --- /dev/null +++ b/echo-js/deployments/localhost/Merkle.json @@ -0,0 +1,222 @@ +{ + "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "hashes", + "type": "bytes32[]" + } + ], + "name": "calculateRootFromPowerOfTwo", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getEmptyTreeHashAtIndex", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_wordIndex", + "type": "uint256" + } + ], + "name": "getHashOfWordAtIndex", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_log2Size", + "type": "uint256" + } + ], + "name": "getMerkleRootFromBytes", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_position", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_logSizeOfReplacement", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_logSizeOfFullDrive", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_replacement", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "siblings", + "type": "bytes32[]" + } + ], + "name": "getRootAfterReplacementInDrive", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xe4cbd6e1b8cbef8003127d5f041b21c21a84068f49c260190b1fc21964eb35cd", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", + "transactionIndex": 0, + "gasUsed": "1317703", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x858f9877a596e31258b46b9e21015991edca5f8dcd71a2eab59a569db6543798", + "transactionHash": "0xe4cbd6e1b8cbef8003127d5f041b21c21a84068f49c260190b1fc21964eb35cd", + "logs": [], + "blockNumber": 4, + "cumulativeGasUsed": "1317703", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"name\":\"calculateRootFromPowerOfTwo\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getEmptyTreeHashAtIndex\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_wordIndex\",\"type\":\"uint256\"}],\"name\":\"getHashOfWordAtIndex\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_log2Size\",\"type\":\"uint256\"}],\"name\":\"getMerkleRootFromBytes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_position\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_logSizeOfReplacement\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_logSizeOfFullDrive\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_replacement\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"siblings\",\"type\":\"bytes32[]\"}],\"name\":\"getRootAfterReplacementInDrive\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"calculateRootFromPowerOfTwo(bytes32[])\":{\"params\":{\"hashes\":\"The array containing power of 2 elements\"},\"returns\":{\"_0\":\"byte32 the root hash being calculated\"}},\"getEmptyTreeHashAtIndex(uint256)\":{\"details\":\"first index is keccak(0), second index is keccak(keccak(0), keccak(0))\",\"params\":{\"_index\":\"of hash wanted\"}},\"getHashOfWordAtIndex(bytes,uint256)\":{\"details\":\"if word is incomplete (< 8 bytes) it gets padded with zeroes\",\"params\":{\"_data\":\"array of bytes\",\"_wordIndex\":\"index of word inside the bytes to get the hash of\"}},\"getMerkleRootFromBytes(bytes,uint256)\":{\"details\":\"_data is padded with zeroes until is multiple of 8root is completed with zero tree until log2size is completehashes are taken word by word (8 bytes by 8 bytes)\",\"params\":{\"_data\":\"array of bytes to be merklelized\",\"_log2Size\":\"log2 of total size of the drive\"}},\"getRootAfterReplacementInDrive(uint256,uint256,uint256,bytes32,bytes32[])\":{\"params\":{\"_logSizeOfFullDrive\":\"log2 of size the full drive, which can be the entire machine\",\"_logSizeOfReplacement\":\"log2 of size the replacement\",\"_position\":\"position of _drive\",\"_replacement\":\"hash of the replacement\",\"siblings\":\"of replacement that merkle root can be calculated\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"calculateRootFromPowerOfTwo(bytes32[])\":{\"notice\":\"Calculate the root of Merkle tree from an array of power of 2 elements\"},\"getEmptyTreeHashAtIndex(uint256)\":{\"notice\":\"Gets precomputed hash of zero in empty tree hashes\"},\"getHashOfWordAtIndex(bytes,uint256)\":{\"notice\":\"Get the hash of a word in an array of bytes\"},\"getMerkleRootFromBytes(bytes,uint256)\":{\"notice\":\"get merkle root of generic array of bytes\"},\"getRootAfterReplacementInDrive(uint256,uint256,uint256,bytes32,bytes32[])\":{\"notice\":\"Gets merkle root hash of drive with a replacement\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Merkle.sol\":\"Merkle\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/CartesiMath.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title CartesiMath\\n/// @author Felipe Argento\\npragma solidity ^0.8.0;\\n\\nlibrary CartesiMath {\\n // mapping values are packed as bytes3 each\\n // see test/TestCartesiMath.ts for decimal values\\n bytes constant log2tableTimes1M =\\n hex\\\"0000000F4240182F421E8480236E082771822AD63A2DC6C0305E8532B04834C96736B3C23876D73A187A3B9D4A3D09003E5EA63FA0C540D17741F28843057D440BA745062945F60246DC1047B917488DC7495ABA4A207C4ADF8A4B98544C4B404CF8AA4DA0E64E44434EE3054F7D6D5013B750A61A5134C851BFF05247BD52CC58534DE753CC8D54486954C19C55384255AC75561E50568DE956FB575766B057D00758376F589CFA5900BA5962BC59C3135A21CA5A7EF15ADA945B34BF5B8D805BE4DF5C3AEA5C8FA95CE3265D356C5D86835DD6735E25455E73005EBFAD5F0B525F55F75F9FA25FE85A60302460770860BD0A61023061467F6189FD61CCAE620E98624FBF62902762CFD5630ECD634D12638AA963C7966403DC643F7F647A8264B4E864EEB56527EC6560906598A365D029660724663D9766738566A8F066DDDA6712476746386779AF67ACAF67DF3A6811526842FA68743268A4FC68D55C6905536934E169640A6992CF69C13169EF326A1CD46A4A186A76FF6AA38C6ACFC0\\\";\\n\\n /// @notice Approximates log2 * 1M\\n /// @param _num number to take log2 * 1M of\\n /// @return approximate log2 times 1M\\n function log2ApproxTimes1M(uint256 _num) public pure returns (uint256) {\\n require(_num > 0, \\\"Number cannot be zero\\\");\\n uint256 leading = 0;\\n\\n if (_num == 1) return 0;\\n\\n while (_num > 128) {\\n _num = _num >> 1;\\n leading += 1;\\n }\\n return (leading * uint256(1000000)) + (getLog2TableTimes1M(_num));\\n }\\n\\n /// @notice navigates log2tableTimes1M\\n /// @param _num number to take log2 of\\n /// @return result after table look-up\\n function getLog2TableTimes1M(uint256 _num) public pure returns (uint256) {\\n bytes3 result = 0;\\n for (uint8 i = 0; i < 3; i++) {\\n bytes3 tempResult = log2tableTimes1M[(_num - 1) * 3 + i];\\n result = result | (tempResult >> (i * 8));\\n }\\n\\n return uint256(uint24(result));\\n }\\n\\n /// @notice get floor of log2 of number\\n /// @param _num number to take floor(log2) of\\n /// @return floor(log2) of _num\\n function getLog2Floor(uint256 _num) public pure returns (uint8) {\\n require(_num != 0, \\\"log of zero is undefined\\\");\\n\\n return uint8(255 - clz(_num));\\n }\\n\\n /// @notice checks if a number is Power of 2\\n /// @param _num number to check\\n /// @return true if number is power of 2, false if not\\n function isPowerOf2(uint256 _num) public pure returns (bool) {\\n if (_num == 0) return false;\\n\\n return _num & (_num - 1) == 0;\\n }\\n\\n /// @notice count trailing zeros\\n /// @param _num number you want the ctz of\\n /// @dev this a binary search implementation\\n function ctz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { n = n + 128; _num = _num >> 128; }\\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) { n = n + 64; _num = _num >> 64; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) { n = n + 32; _num = _num >> 32; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) { n = n + 16; _num = _num >> 16; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) { n = n + 8; _num = _num >> 8; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) { n = n + 4; _num = _num >> 4; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) { n = n + 2; _num = _num >> 2; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n\\n /// @notice count leading zeros\\n /// @param _num number you want the clz of\\n /// @dev this a binary search implementation\\n function clz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 == 0) { n = n + 128; _num = _num << 128; }\\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) { n = n + 64; _num = _num << 64; }\\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) { n = n + 32; _num = _num << 32; }\\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 16; _num = _num << 16; }\\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 8; _num = _num << 8; }\\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 4; _num = _num << 4; }\\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 2; _num = _num << 2; }\\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n}\\n\",\"keccak256\":\"0x28b74012e966438edff701decdc5ffd207b3f0244af65fbd7d397050986e58d4\",\"license\":\"Apache-2.0\"},\"contracts/Merkle.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Library for Merkle proofs\\npragma solidity ^0.8.0;\\n\\nimport \\\"./CartesiMath.sol\\\";\\n\\nlibrary Merkle {\\n using CartesiMath for uint256;\\n\\n uint128 constant L_WORD_SIZE = 3; // word = 8 bytes, log = 3\\n // number of hashes in EMPTY_TREE_HASHES\\n uint128 constant EMPTY_TREE_SIZE = 1952; // 61*32=1952. 32 bytes per 61 indexes (64 words)\\n\\n // merkle root hashes of trees of zero concatenated\\n // 32 bytes for each root, first one is keccak(0), second one is\\n // keccak(keccack(0), keccak(0)) and so on\\n\\n bytes constant EMPTY_TREE_HASHES =\\n hex\\\"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce4d9470a821fbe90117ec357e30bad9305732fb19ddf54a07dd3e29f440619254ae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a233fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9c37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e68e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e30930b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90cd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efed8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0c9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e6163e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b72122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046f7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec517a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca892b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e152499af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f27d86025599a41233848702f0cfc0437b445682df51147a632a0a083d2d38b5e13e466a8935afff58bb533b3ef5d27fba63ee6b0fd9e67ff20af9d50deee3f8bf065ec220c1fd4ba57e341261d55997f85d66d32152526736872693d2b437a233e2337b715f6ac9a6a272622fdc2d67fcfe1da3459f8dab4ed7e40a657a54c36766c5e8ac9a88b35b05c34747e6507f6b044ab66180dc76ac1a696de03189593fedc0d0dbbd855c8ead673544899b0960e4a5a7ca43b4ef90afe607de7698caefdc242788f654b57a4fb32a71b335ef6ff9a4cc118b282b53bdd6d6192b7a82c3c5126b9c7e33c8e5a5ac9738b8bd31247fb7402054f97b573e8abb9faad219f4fd085aceaa7f542d787ee4196d365f3cc566e7bbcfbfd451230c48d804c017d21e2d8fa914e2559bb72bf0ab78c8ab92f00ef0d0d576eccdd486b64138a4172674857e543d1d5b639058dd908186597e366ad5f3d9c7ceaff44d04d1550b8d33abc751df07437834ba5acb32328a396994aebb3c40f759c2d6d7a3cb5377e55d5d218ef5a296dda8ddc355f3f50c3d0b660a51dfa4d98a6a5a33564556cf83c1373a814641d6a1dcef97b883fee61bb84fe60a3409340217e629cc7e4dcc93b85d8820921ff5826148b60e6939acd7838e1d7f20562bff8ee4b5ec4a05ad997a57b9796fdcb2eda87883c2640b072b140b946bfdf6575cacc066fdae04f6951e63624cbd316a677cad529bbe4e97b9144e4bc06c4afd1de55dd3e1175f90423847a230d34dfb71ed56f2965a7f6c72e6aa33c24c303fd67745d632656c5ef90bec80f4f5d1daa251988826cef375c81c36bf457e09687056f924677cb0bccf98dff81e014ce25f2d132497923e267363963cdf4302c5049d63131dc03fd95f65d8b6aa5934f817252c028c90f56d413b9d5d10d89790707dae2fabb249f649929927c21dd71e3f656826de5451c5da375aadecbd59d5ebf3a31fae65ac1b316a1611f1b276b26530f58d7247df459ce1f86db1d734f6f811932f042cee45d0e455306d01081bc3384f82c5fb2aacaa19d89cdfa46cc916eac61121475ba2e6191b4feecbe1789717021a158ace5d06744b40f551076b67cd63af60007f8c99876e1424883a45ec49d497ddaf808a5521ca74a999ab0b3c7aa9c80f85e93977ec61ce68b20307a1a81f71ca645b568fcd319ccbb5f651e87b707d37c39e15f945ea69e2f7c7d2ccc85b7e654c07e96f0636ae4044fe0e38590b431795ad0f8647bdd613713ada493cc17efd313206380e6a685b8198475bbd021c6e9d94daab2214947127506073e44d5408ba166c512a0b86805d07f5a44d3c41706be2bc15e712e55805248b92e8677d90f6d284d1d6ffaff2c430657042a0e82624fa3717b06cc0a6fd12230ea586dae83019fb9e06034ed2803c98d554b93c9a52348cafff75c40174a91f9ae6b8647854a156029f0b88b83316663ce574a4978277bb6bb27a31085634b6ec78864b6d8201c7e93903d75815067e378289a3d072ae172dafa6a452470f8d645bebfad9779594fc0784bb764a22e3a8181d93db7bf97893c414217a618ccb14caa9e92e8c61673afc9583662e812adba1f87a9c68202d60e909efab43c42c0cb00695fc7f1ffe67c75ca894c3c51e1e5e731360199e600f6ced9a87b2a6a87e70bf251bb5075ab222138288164b2eda727515ea7de12e2496d4fe42ea8d1a120c03cf9c50622c2afe4acb0dad98fd62d07ab4e828a94495f6d1ab973982c7ccbe6c1fae02788e4422ae22282fa49cbdb04ba54a7a238c6fc41187451383460762c06d1c8a72b9cd718866ad4b689e10c9a8c38fe5ef045bd785b01e980fc82c7e3532ce81876b778dd9f1ceeba4478e86411fb6fdd790683916ca832592485093644e8760cd7b4c01dba1ccc82b661bf13f0e3f34acd6b88\\\";\\n\\n /// @notice Gets merkle root hash of drive with a replacement\\n /// @param _position position of _drive\\n /// @param _logSizeOfReplacement log2 of size the replacement\\n /// @param _logSizeOfFullDrive log2 of size the full drive, which can be the entire machine\\n /// @param _replacement hash of the replacement\\n /// @param siblings of replacement that merkle root can be calculated\\n function getRootAfterReplacementInDrive(\\n uint256 _position,\\n uint256 _logSizeOfReplacement,\\n uint256 _logSizeOfFullDrive,\\n bytes32 _replacement,\\n bytes32[] calldata siblings\\n ) public pure returns (bytes32) {\\n require(\\n _logSizeOfFullDrive >= _logSizeOfReplacement &&\\n _logSizeOfReplacement >= 3 &&\\n _logSizeOfFullDrive <= 64,\\n \\\"3 <= logSizeOfReplacement <= logSizeOfFullDrive <= 64\\\"\\n );\\n\\n uint256 size = 1 << _logSizeOfReplacement;\\n\\n require(((size - 1) & _position) == 0, \\\"Position is not aligned\\\");\\n require(\\n siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement,\\n \\\"Proof length does not match\\\"\\n );\\n\\n for (uint256 i; i < siblings.length; i++) {\\n if ((_position & (size << i)) == 0) {\\n _replacement = keccak256(\\n abi.encodePacked(_replacement, siblings[i])\\n );\\n } else {\\n _replacement = keccak256(\\n abi.encodePacked(siblings[i], _replacement)\\n );\\n }\\n }\\n\\n return _replacement;\\n }\\n\\n /// @notice Gets precomputed hash of zero in empty tree hashes\\n /// @param _index of hash wanted\\n /// @dev first index is keccak(0), second index is keccak(keccak(0), keccak(0))\\n function getEmptyTreeHashAtIndex(uint256 _index)\\n public\\n pure\\n returns (bytes32)\\n {\\n uint256 start = _index * 32;\\n require(EMPTY_TREE_SIZE >= start + 32, \\\"index out of bounds\\\");\\n bytes32 hashedZeros;\\n bytes memory zeroTree = EMPTY_TREE_HASHES;\\n\\n // first word is length, then skip index words\\n assembly {\\n hashedZeros := mload(add(add(zeroTree, 0x20), start))\\n }\\n return hashedZeros;\\n }\\n\\n /// @notice get merkle root of generic array of bytes\\n /// @param _data array of bytes to be merklelized\\n /// @param _log2Size log2 of total size of the drive\\n /// @dev _data is padded with zeroes until is multiple of 8\\n /// @dev root is completed with zero tree until log2size is complete\\n /// @dev hashes are taken word by word (8 bytes by 8 bytes)\\n function getMerkleRootFromBytes(bytes calldata _data, uint256 _log2Size)\\n public\\n pure\\n returns (bytes32)\\n {\\n require(_log2Size >= 3 && _log2Size <= 64, \\\"range of log2Size: [3,64]\\\");\\n\\n // if _data is empty return pristine drive of size log2size\\n if (_data.length == 0) return getEmptyTreeHashAtIndex(_log2Size - 3);\\n\\n // total size of the drive in words\\n uint256 size = 1 << (_log2Size - 3);\\n require(\\n size << L_WORD_SIZE >= _data.length,\\n \\\"data is bigger than drive\\\"\\n );\\n // the stack depth is log2(_data.length / 8) + 2\\n uint256 stack_depth = 2 +\\n ((_data.length) >> L_WORD_SIZE).getLog2Floor();\\n bytes32[] memory stack = new bytes32[](stack_depth);\\n\\n uint256 numOfHashes; // total number of hashes on stack (counting levels)\\n uint256 stackLength; // total length of stack\\n uint256 numOfJoins; // number of hashes of the same level on stack\\n uint256 topStackLevel; // hash level of the top of the stack\\n\\n while (numOfHashes < size) {\\n if ((numOfHashes << L_WORD_SIZE) < _data.length) {\\n // we still have words to hash\\n stack[stackLength] = getHashOfWordAtIndex(_data, numOfHashes);\\n numOfHashes++;\\n\\n numOfJoins = numOfHashes;\\n } else {\\n // since padding happens in hashOfWordAtIndex function\\n // we only need to complete the stack with pre-computed\\n // hash(0), hash(hash(0),hash(0)) and so on\\n topStackLevel = numOfHashes.ctz();\\n\\n stack[stackLength] = getEmptyTreeHashAtIndex(topStackLevel);\\n\\n //Empty Tree Hash summarizes many hashes\\n numOfHashes = numOfHashes + (1 << topStackLevel);\\n numOfJoins = numOfHashes >> topStackLevel;\\n }\\n\\n stackLength++;\\n\\n // while there are joins, hash top of stack together\\n while (numOfJoins & 1 == 0) {\\n bytes32 h2 = stack[stackLength - 1];\\n bytes32 h1 = stack[stackLength - 2];\\n\\n stack[stackLength - 2] = keccak256(abi.encodePacked(h1, h2));\\n stackLength = stackLength - 1; // remove hashes from stack\\n\\n numOfJoins = numOfJoins >> 1;\\n }\\n }\\n require(stackLength == 1, \\\"stack error\\\");\\n\\n return stack[0];\\n }\\n\\n /// @notice Get the hash of a word in an array of bytes\\n /// @param _data array of bytes\\n /// @param _wordIndex index of word inside the bytes to get the hash of\\n /// @dev if word is incomplete (< 8 bytes) it gets padded with zeroes\\n function getHashOfWordAtIndex(bytes calldata _data, uint256 _wordIndex)\\n public\\n pure\\n returns (bytes32)\\n {\\n uint256 start = _wordIndex << L_WORD_SIZE;\\n uint256 end = start + (1 << L_WORD_SIZE);\\n\\n // TODO: in .lua this just returns zero, but this might be more consistent\\n require(start <= _data.length, \\\"word out of bounds\\\");\\n\\n if (end <= _data.length) {\\n return keccak256(abi.encodePacked(_data[start:end]));\\n }\\n\\n // word is incomplete\\n // fill paddedSlice with incomplete words - the rest is going to be bytes(0)\\n bytes memory paddedSlice = new bytes(8);\\n uint256 remaining = _data.length - start;\\n\\n for (uint256 i; i < remaining; i++) {\\n paddedSlice[i] = _data[start + i];\\n }\\n\\n return keccak256(paddedSlice);\\n }\\n\\n /// @notice Calculate the root of Merkle tree from an array of power of 2 elements\\n /// @param hashes The array containing power of 2 elements\\n /// @return byte32 the root hash being calculated\\n function calculateRootFromPowerOfTwo(bytes32[] memory hashes)\\n public\\n pure\\n returns (bytes32)\\n {\\n // revert when the input is not of power of 2\\n require((hashes.length).isPowerOf2(), \\\"array len not power of 2\\\");\\n\\n if (hashes.length == 1) {\\n return hashes[0];\\n } else {\\n bytes32[] memory newHashes = new bytes32[](hashes.length >> 1);\\n\\n for (uint256 i; i < hashes.length; i += 2) {\\n newHashes[i >> 1] = keccak256(\\n abi.encodePacked(hashes[i], hashes[i + 1])\\n );\\n }\\n\\n return calculateRootFromPowerOfTwo(newHashes);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe9896db44cc4dab335a3e776c629186824823d316d902b2efecb4b0a3e3dfdb7\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6116df61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100615760003560e01c806334bd712d14610066578063451a10551461008b57806379de46011461009e57806382b0eab8146100b1578063c84583a1146100c4575b600080fd5b610079610074366004610cbd565b6100d7565b60405190815260200160405180910390f35b610079610099366004610d30565b610245565b6100796100ac366004610d60565b6102d6565b6100796100bf366004610bdd565b610505565b6100796100d2366004610cbd565b610756565b6000600382901b816100ea600883610e4f565b9050848211156101365760405162461bcd60e51b8152602060048201526012602482015271776f7264206f7574206f6620626f756e647360701b60448201526064015b60405180910390fd5b8481116101795761014981838789610e27565b60405160200161015a929190610e17565b604051602081830303815290604052805190602001209250505061023e565b60408051600880825281830190925260009160208201818036833701905050905060006101a68488610eab565b905060005b8181101561022f5788886101bf8388610e4f565b8181106101dc57634e487b7160e01b600052603260045260246000fd5b9050013560f81c60f81b83828151811061020657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053508061022781610ec2565b9150506101ab565b50508051602090910120925050505b9392505050565b600080610253836020610e8c565b9050610260816020610e4f565b6107a010156102a75760405162461bcd60e51b8152602060048201526013602482015272696e646578206f7574206f6620626f756e647360681b604482015260640161012d565b600080604051806107c001604052806107a08152602001610f0a6107a091399290920160200151949350505050565b60008585101580156102e9575060038610155b80156102f6575060408511155b6103605760405162461bcd60e51b815260206004820152603560248201527f33203c3d206c6f6753697a654f665265706c6163656d656e74203c3d206c6f6760448201527414da5e9953d9919d5b1b111c9a5d99480f0f480d8d605a1b606482015260840161012d565b600180871b9088906103729083610eab565b16156103c05760405162461bcd60e51b815260206004820152601760248201527f506f736974696f6e206973206e6f7420616c69676e6564000000000000000000604482015260640161012d565b6103ca8787610eab565b83146104185760405162461bcd60e51b815260206004820152601b60248201527f50726f6f66206c656e67746820646f6573206e6f74206d617463680000000000604482015260640161012d565b60005b838110156104f85781811b891661048b578585858381811061044d57634e487b7160e01b600052603260045260246000fd5b9050602002013560405160200161046e929190918252602082015260400190565b6040516020818303038152906040528051906020012095506104e6565b8484828181106104ab57634e487b7160e01b600052603260045260246000fd5b90506020020135866040516020016104cd929190918252602082015260400190565b6040516020818303038152906040528051906020012095505b806104f081610ec2565b91505061041b565b5093979650505050505050565b805160405163d82ae4b160e01b8152600091739fE46736679d2D9a65F0992F2272dE9f3c7fa6e09163d82ae4b1916105439160040190815260200190565b60206040518083038186803b15801561055b57600080fd5b505af415801561056f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105939190610c9d565b6105df5760405162461bcd60e51b815260206004820152601860248201527f6172726179206c656e206e6f7420706f776572206f6620320000000000000000604482015260640161012d565b815160011415610619578160008151811061060a57634e487b7160e01b600052603260045260246000fd5b60200260200101519050919050565b600060018351901c67ffffffffffffffff81111561064757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610670578160200160208202803683370190505b50905060005b835181101561074c5783818151811061069f57634e487b7160e01b600052603260045260246000fd5b6020026020010151848260016106b59190610e4f565b815181106106d357634e487b7160e01b600052603260045260246000fd5b60200260200101516040516020016106f5929190918252602082015260400190565b6040516020818303038152906040528051906020012082600183901c8151811061072f57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610745600282610e4f565b9050610676565b5061023e81610505565b60006003821015801561076a575060408211155b6107b65760405162461bcd60e51b815260206004820152601960248201527f72616e6765206f66206c6f673253697a653a205b332c36345d00000000000000604482015260640161012d565b826107d0576107c9610099600384610eab565b905061023e565b60006107dd600384610eab565b6001901b9050600381901b8411156108375760405162461bcd60e51b815260206004820152601960248201527f6461746120697320626967676572207468616e20647269766500000000000000604482015260640161012d565b6040516306c8e54b60e01b8152600385901c6004820152600090739fE46736679d2D9a65F0992F2272dE9f3c7fa6e0906306c8e54b9060240160206040518083038186803b15801561088857600080fd5b505af415801561089c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c09190610df6565b6108cb906002610e67565b60ff16905060008167ffffffffffffffff8111156108f957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610922578160200160208202803683370190505b5090506000806000805b86841015610b6657600384901b8a111561098b5761094b8b8b866100d7565b85848151811061096b57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528361098081610ec2565b945050839150610a59565b60405163052dcf5f60e31b815260048101859052739fE46736679d2D9a65F0992F2272dE9f3c7fa6e09063296e7af89060240160206040518083038186803b1580156109d657600080fd5b505af41580156109ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0e9190610d48565b9050610a1981610245565b858481518110610a3957634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610a516001821b85610e4f565b935083811c91505b82610a6381610ec2565b9350505b60018216610b6157600085610a7d600186610eab565b81518110610a9b57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600086600286610ab59190610eab565b81518110610ad357634e487b7160e01b600052603260045260246000fd5b602002602001015190508082604051602001610af9929190918252602082015260400190565b6040516020818303038152906040528051906020012087600287610b1d9190610eab565b81518110610b3b57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610b51600186610eab565b9450600184901c93505050610a67565b61092c565b82600114610ba45760405162461bcd60e51b815260206004820152600b60248201526a39ba30b1b59032b93937b960a91b604482015260640161012d565b84600081518110610bc557634e487b7160e01b600052603260045260246000fd5b60200260200101519750505050505050509392505050565b60006020808385031215610bef578182fd5b823567ffffffffffffffff80821115610c06578384fd5b818501915085601f830112610c19578384fd5b813581811115610c2b57610c2b610ef3565b8060051b604051601f19603f83011681018181108582111715610c5057610c50610ef3565b604052828152858101935084860182860187018a1015610c6e578788fd5b8795505b83861015610c90578035855260019590950194938601938601610c72565b5098975050505050505050565b600060208284031215610cae578081fd5b8151801515811461023e578182fd5b600080600060408486031215610cd1578182fd5b833567ffffffffffffffff80821115610ce8578384fd5b818601915086601f830112610cfb578384fd5b813581811115610d09578485fd5b876020828501011115610d1a578485fd5b6020928301989097509590910135949350505050565b600060208284031215610d41578081fd5b5035919050565b600060208284031215610d59578081fd5b5051919050565b60008060008060008060a08789031215610d78578182fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff80821115610dab578384fd5b818901915089601f830112610dbe578384fd5b813581811115610dcc578485fd5b8a60208260051b8501011115610de0578485fd5b6020830194508093505050509295509295509295565b600060208284031215610e07578081fd5b815160ff8116811461023e578182fd5b8183823760009101908152919050565b60008085851115610e36578182fd5b83861115610e42578182fd5b5050820193919092039150565b60008219821115610e6257610e62610edd565b500190565b600060ff821660ff84168060ff03821115610e8457610e84610edd565b019392505050565b6000816000190483118215151615610ea657610ea6610edd565b500290565b600082821015610ebd57610ebd610edd565b500390565b6000600019821415610ed657610ed6610edd565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfe011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce4d9470a821fbe90117ec357e30bad9305732fb19ddf54a07dd3e29f440619254ae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a233fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9c37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e68e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e30930b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90cd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efed8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0c9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e6163e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b72122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046f7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec517a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca892b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e152499af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f27d86025599a41233848702f0cfc0437b445682df51147a632a0a083d2d38b5e13e466a8935afff58bb533b3ef5d27fba63ee6b0fd9e67ff20af9d50deee3f8bf065ec220c1fd4ba57e341261d55997f85d66d32152526736872693d2b437a233e2337b715f6ac9a6a272622fdc2d67fcfe1da3459f8dab4ed7e40a657a54c36766c5e8ac9a88b35b05c34747e6507f6b044ab66180dc76ac1a696de03189593fedc0d0dbbd855c8ead673544899b0960e4a5a7ca43b4ef90afe607de7698caefdc242788f654b57a4fb32a71b335ef6ff9a4cc118b282b53bdd6d6192b7a82c3c5126b9c7e33c8e5a5ac9738b8bd31247fb7402054f97b573e8abb9faad219f4fd085aceaa7f542d787ee4196d365f3cc566e7bbcfbfd451230c48d804c017d21e2d8fa914e2559bb72bf0ab78c8ab92f00ef0d0d576eccdd486b64138a4172674857e543d1d5b639058dd908186597e366ad5f3d9c7ceaff44d04d1550b8d33abc751df07437834ba5acb32328a396994aebb3c40f759c2d6d7a3cb5377e55d5d218ef5a296dda8ddc355f3f50c3d0b660a51dfa4d98a6a5a33564556cf83c1373a814641d6a1dcef97b883fee61bb84fe60a3409340217e629cc7e4dcc93b85d8820921ff5826148b60e6939acd7838e1d7f20562bff8ee4b5ec4a05ad997a57b9796fdcb2eda87883c2640b072b140b946bfdf6575cacc066fdae04f6951e63624cbd316a677cad529bbe4e97b9144e4bc06c4afd1de55dd3e1175f90423847a230d34dfb71ed56f2965a7f6c72e6aa33c24c303fd67745d632656c5ef90bec80f4f5d1daa251988826cef375c81c36bf457e09687056f924677cb0bccf98dff81e014ce25f2d132497923e267363963cdf4302c5049d63131dc03fd95f65d8b6aa5934f817252c028c90f56d413b9d5d10d89790707dae2fabb249f649929927c21dd71e3f656826de5451c5da375aadecbd59d5ebf3a31fae65ac1b316a1611f1b276b26530f58d7247df459ce1f86db1d734f6f811932f042cee45d0e455306d01081bc3384f82c5fb2aacaa19d89cdfa46cc916eac61121475ba2e6191b4feecbe1789717021a158ace5d06744b40f551076b67cd63af60007f8c99876e1424883a45ec49d497ddaf808a5521ca74a999ab0b3c7aa9c80f85e93977ec61ce68b20307a1a81f71ca645b568fcd319ccbb5f651e87b707d37c39e15f945ea69e2f7c7d2ccc85b7e654c07e96f0636ae4044fe0e38590b431795ad0f8647bdd613713ada493cc17efd313206380e6a685b8198475bbd021c6e9d94daab2214947127506073e44d5408ba166c512a0b86805d07f5a44d3c41706be2bc15e712e55805248b92e8677d90f6d284d1d6ffaff2c430657042a0e82624fa3717b06cc0a6fd12230ea586dae83019fb9e06034ed2803c98d554b93c9a52348cafff75c40174a91f9ae6b8647854a156029f0b88b83316663ce574a4978277bb6bb27a31085634b6ec78864b6d8201c7e93903d75815067e378289a3d072ae172dafa6a452470f8d645bebfad9779594fc0784bb764a22e3a8181d93db7bf97893c414217a618ccb14caa9e92e8c61673afc9583662e812adba1f87a9c68202d60e909efab43c42c0cb00695fc7f1ffe67c75ca894c3c51e1e5e731360199e600f6ced9a87b2a6a87e70bf251bb5075ab222138288164b2eda727515ea7de12e2496d4fe42ea8d1a120c03cf9c50622c2afe4acb0dad98fd62d07ab4e828a94495f6d1ab973982c7ccbe6c1fae02788e4422ae22282fa49cbdb04ba54a7a238c6fc41187451383460762c06d1c8a72b9cd718866ad4b689e10c9a8c38fe5ef045bd785b01e980fc82c7e3532ce81876b778dd9f1ceeba4478e86411fb6fdd790683916ca832592485093644e8760cd7b4c01dba1ccc82b661bf13f0e3f34acd6b88a2646970667358221220be79c972192069d105a5fc9aae66c9ff55a7f4076d708aa33a4f2ecaec2873e364736f6c63430008040033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100615760003560e01c806334bd712d14610066578063451a10551461008b57806379de46011461009e57806382b0eab8146100b1578063c84583a1146100c4575b600080fd5b610079610074366004610cbd565b6100d7565b60405190815260200160405180910390f35b610079610099366004610d30565b610245565b6100796100ac366004610d60565b6102d6565b6100796100bf366004610bdd565b610505565b6100796100d2366004610cbd565b610756565b6000600382901b816100ea600883610e4f565b9050848211156101365760405162461bcd60e51b8152602060048201526012602482015271776f7264206f7574206f6620626f756e647360701b60448201526064015b60405180910390fd5b8481116101795761014981838789610e27565b60405160200161015a929190610e17565b604051602081830303815290604052805190602001209250505061023e565b60408051600880825281830190925260009160208201818036833701905050905060006101a68488610eab565b905060005b8181101561022f5788886101bf8388610e4f565b8181106101dc57634e487b7160e01b600052603260045260246000fd5b9050013560f81c60f81b83828151811061020657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053508061022781610ec2565b9150506101ab565b50508051602090910120925050505b9392505050565b600080610253836020610e8c565b9050610260816020610e4f565b6107a010156102a75760405162461bcd60e51b8152602060048201526013602482015272696e646578206f7574206f6620626f756e647360681b604482015260640161012d565b600080604051806107c001604052806107a08152602001610f0a6107a091399290920160200151949350505050565b60008585101580156102e9575060038610155b80156102f6575060408511155b6103605760405162461bcd60e51b815260206004820152603560248201527f33203c3d206c6f6753697a654f665265706c6163656d656e74203c3d206c6f6760448201527414da5e9953d9919d5b1b111c9a5d99480f0f480d8d605a1b606482015260840161012d565b600180871b9088906103729083610eab565b16156103c05760405162461bcd60e51b815260206004820152601760248201527f506f736974696f6e206973206e6f7420616c69676e6564000000000000000000604482015260640161012d565b6103ca8787610eab565b83146104185760405162461bcd60e51b815260206004820152601b60248201527f50726f6f66206c656e67746820646f6573206e6f74206d617463680000000000604482015260640161012d565b60005b838110156104f85781811b891661048b578585858381811061044d57634e487b7160e01b600052603260045260246000fd5b9050602002013560405160200161046e929190918252602082015260400190565b6040516020818303038152906040528051906020012095506104e6565b8484828181106104ab57634e487b7160e01b600052603260045260246000fd5b90506020020135866040516020016104cd929190918252602082015260400190565b6040516020818303038152906040528051906020012095505b806104f081610ec2565b91505061041b565b5093979650505050505050565b805160405163d82ae4b160e01b815260009173__$8b7ebe2a69e01741840a6648963dfd5409$__9163d82ae4b1916105439160040190815260200190565b60206040518083038186803b15801561055b57600080fd5b505af415801561056f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105939190610c9d565b6105df5760405162461bcd60e51b815260206004820152601860248201527f6172726179206c656e206e6f7420706f776572206f6620320000000000000000604482015260640161012d565b815160011415610619578160008151811061060a57634e487b7160e01b600052603260045260246000fd5b60200260200101519050919050565b600060018351901c67ffffffffffffffff81111561064757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610670578160200160208202803683370190505b50905060005b835181101561074c5783818151811061069f57634e487b7160e01b600052603260045260246000fd5b6020026020010151848260016106b59190610e4f565b815181106106d357634e487b7160e01b600052603260045260246000fd5b60200260200101516040516020016106f5929190918252602082015260400190565b6040516020818303038152906040528051906020012082600183901c8151811061072f57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610745600282610e4f565b9050610676565b5061023e81610505565b60006003821015801561076a575060408211155b6107b65760405162461bcd60e51b815260206004820152601960248201527f72616e6765206f66206c6f673253697a653a205b332c36345d00000000000000604482015260640161012d565b826107d0576107c9610099600384610eab565b905061023e565b60006107dd600384610eab565b6001901b9050600381901b8411156108375760405162461bcd60e51b815260206004820152601960248201527f6461746120697320626967676572207468616e20647269766500000000000000604482015260640161012d565b6040516306c8e54b60e01b8152600385901c600482015260009073__$8b7ebe2a69e01741840a6648963dfd5409$__906306c8e54b9060240160206040518083038186803b15801561088857600080fd5b505af415801561089c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c09190610df6565b6108cb906002610e67565b60ff16905060008167ffffffffffffffff8111156108f957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610922578160200160208202803683370190505b5090506000806000805b86841015610b6657600384901b8a111561098b5761094b8b8b866100d7565b85848151811061096b57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528361098081610ec2565b945050839150610a59565b60405163052dcf5f60e31b81526004810185905273__$8b7ebe2a69e01741840a6648963dfd5409$__9063296e7af89060240160206040518083038186803b1580156109d657600080fd5b505af41580156109ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0e9190610d48565b9050610a1981610245565b858481518110610a3957634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610a516001821b85610e4f565b935083811c91505b82610a6381610ec2565b9350505b60018216610b6157600085610a7d600186610eab565b81518110610a9b57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600086600286610ab59190610eab565b81518110610ad357634e487b7160e01b600052603260045260246000fd5b602002602001015190508082604051602001610af9929190918252602082015260400190565b6040516020818303038152906040528051906020012087600287610b1d9190610eab565b81518110610b3b57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610b51600186610eab565b9450600184901c93505050610a67565b61092c565b82600114610ba45760405162461bcd60e51b815260206004820152600b60248201526a39ba30b1b59032b93937b960a91b604482015260640161012d565b84600081518110610bc557634e487b7160e01b600052603260045260246000fd5b60200260200101519750505050505050509392505050565b60006020808385031215610bef578182fd5b823567ffffffffffffffff80821115610c06578384fd5b818501915085601f830112610c19578384fd5b813581811115610c2b57610c2b610ef3565b8060051b604051601f19603f83011681018181108582111715610c5057610c50610ef3565b604052828152858101935084860182860187018a1015610c6e578788fd5b8795505b83861015610c90578035855260019590950194938601938601610c72565b5098975050505050505050565b600060208284031215610cae578081fd5b8151801515811461023e578182fd5b600080600060408486031215610cd1578182fd5b833567ffffffffffffffff80821115610ce8578384fd5b818601915086601f830112610cfb578384fd5b813581811115610d09578485fd5b876020828501011115610d1a578485fd5b6020928301989097509590910135949350505050565b600060208284031215610d41578081fd5b5035919050565b600060208284031215610d59578081fd5b5051919050565b60008060008060008060a08789031215610d78578182fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff80821115610dab578384fd5b818901915089601f830112610dbe578384fd5b813581811115610dcc578485fd5b8a60208260051b8501011115610de0578485fd5b6020830194508093505050509295509295509295565b600060208284031215610e07578081fd5b815160ff8116811461023e578182fd5b8183823760009101908152919050565b60008085851115610e36578182fd5b83861115610e42578182fd5b5050820193919092039150565b60008219821115610e6257610e62610edd565b500190565b600060ff821660ff84168060ff03821115610e8457610e84610edd565b019392505050565b6000816000190483118215151615610ea657610ea6610edd565b500290565b600082821015610ebd57610ebd610edd565b500390565b6000600019821415610ed657610ed6610edd565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfe011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce4d9470a821fbe90117ec357e30bad9305732fb19ddf54a07dd3e29f440619254ae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a233fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9c37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e68e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e30930b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90cd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efed8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0c9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e6163e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b72122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046f7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec517a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca892b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e152499af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f27d86025599a41233848702f0cfc0437b445682df51147a632a0a083d2d38b5e13e466a8935afff58bb533b3ef5d27fba63ee6b0fd9e67ff20af9d50deee3f8bf065ec220c1fd4ba57e341261d55997f85d66d32152526736872693d2b437a233e2337b715f6ac9a6a272622fdc2d67fcfe1da3459f8dab4ed7e40a657a54c36766c5e8ac9a88b35b05c34747e6507f6b044ab66180dc76ac1a696de03189593fedc0d0dbbd855c8ead673544899b0960e4a5a7ca43b4ef90afe607de7698caefdc242788f654b57a4fb32a71b335ef6ff9a4cc118b282b53bdd6d6192b7a82c3c5126b9c7e33c8e5a5ac9738b8bd31247fb7402054f97b573e8abb9faad219f4fd085aceaa7f542d787ee4196d365f3cc566e7bbcfbfd451230c48d804c017d21e2d8fa914e2559bb72bf0ab78c8ab92f00ef0d0d576eccdd486b64138a4172674857e543d1d5b639058dd908186597e366ad5f3d9c7ceaff44d04d1550b8d33abc751df07437834ba5acb32328a396994aebb3c40f759c2d6d7a3cb5377e55d5d218ef5a296dda8ddc355f3f50c3d0b660a51dfa4d98a6a5a33564556cf83c1373a814641d6a1dcef97b883fee61bb84fe60a3409340217e629cc7e4dcc93b85d8820921ff5826148b60e6939acd7838e1d7f20562bff8ee4b5ec4a05ad997a57b9796fdcb2eda87883c2640b072b140b946bfdf6575cacc066fdae04f6951e63624cbd316a677cad529bbe4e97b9144e4bc06c4afd1de55dd3e1175f90423847a230d34dfb71ed56f2965a7f6c72e6aa33c24c303fd67745d632656c5ef90bec80f4f5d1daa251988826cef375c81c36bf457e09687056f924677cb0bccf98dff81e014ce25f2d132497923e267363963cdf4302c5049d63131dc03fd95f65d8b6aa5934f817252c028c90f56d413b9d5d10d89790707dae2fabb249f649929927c21dd71e3f656826de5451c5da375aadecbd59d5ebf3a31fae65ac1b316a1611f1b276b26530f58d7247df459ce1f86db1d734f6f811932f042cee45d0e455306d01081bc3384f82c5fb2aacaa19d89cdfa46cc916eac61121475ba2e6191b4feecbe1789717021a158ace5d06744b40f551076b67cd63af60007f8c99876e1424883a45ec49d497ddaf808a5521ca74a999ab0b3c7aa9c80f85e93977ec61ce68b20307a1a81f71ca645b568fcd319ccbb5f651e87b707d37c39e15f945ea69e2f7c7d2ccc85b7e654c07e96f0636ae4044fe0e38590b431795ad0f8647bdd613713ada493cc17efd313206380e6a685b8198475bbd021c6e9d94daab2214947127506073e44d5408ba166c512a0b86805d07f5a44d3c41706be2bc15e712e55805248b92e8677d90f6d284d1d6ffaff2c430657042a0e82624fa3717b06cc0a6fd12230ea586dae83019fb9e06034ed2803c98d554b93c9a52348cafff75c40174a91f9ae6b8647854a156029f0b88b83316663ce574a4978277bb6bb27a31085634b6ec78864b6d8201c7e93903d75815067e378289a3d072ae172dafa6a452470f8d645bebfad9779594fc0784bb764a22e3a8181d93db7bf97893c414217a618ccb14caa9e92e8c61673afc9583662e812adba1f87a9c68202d60e909efab43c42c0cb00695fc7f1ffe67c75ca894c3c51e1e5e731360199e600f6ced9a87b2a6a87e70bf251bb5075ab222138288164b2eda727515ea7de12e2496d4fe42ea8d1a120c03cf9c50622c2afe4acb0dad98fd62d07ab4e828a94495f6d1ab973982c7ccbe6c1fae02788e4422ae22282fa49cbdb04ba54a7a238c6fc41187451383460762c06d1c8a72b9cd718866ad4b689e10c9a8c38fe5ef045bd785b01e980fc82c7e3532ce81876b778dd9f1ceeba4478e86411fb6fdd790683916ca832592485093644e8760cd7b4c01dba1ccc82b661bf13f0e3f34acd6b88a2646970667358221220be79c972192069d105a5fc9aae66c9ff55a7f4076d708aa33a4f2ecaec2873e364736f6c63430008040033", + "libraries": { + "CartesiMath": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" + }, + "devdoc": { + "kind": "dev", + "methods": { + "calculateRootFromPowerOfTwo(bytes32[])": { + "params": { + "hashes": "The array containing power of 2 elements" + }, + "returns": { + "_0": "byte32 the root hash being calculated" + } + }, + "getEmptyTreeHashAtIndex(uint256)": { + "details": "first index is keccak(0), second index is keccak(keccak(0), keccak(0))", + "params": { + "_index": "of hash wanted" + } + }, + "getHashOfWordAtIndex(bytes,uint256)": { + "details": "if word is incomplete (< 8 bytes) it gets padded with zeroes", + "params": { + "_data": "array of bytes", + "_wordIndex": "index of word inside the bytes to get the hash of" + } + }, + "getMerkleRootFromBytes(bytes,uint256)": { + "details": "_data is padded with zeroes until is multiple of 8root is completed with zero tree until log2size is completehashes are taken word by word (8 bytes by 8 bytes)", + "params": { + "_data": "array of bytes to be merklelized", + "_log2Size": "log2 of total size of the drive" + } + }, + "getRootAfterReplacementInDrive(uint256,uint256,uint256,bytes32,bytes32[])": { + "params": { + "_logSizeOfFullDrive": "log2 of size the full drive, which can be the entire machine", + "_logSizeOfReplacement": "log2 of size the replacement", + "_position": "position of _drive", + "_replacement": "hash of the replacement", + "siblings": "of replacement that merkle root can be calculated" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "calculateRootFromPowerOfTwo(bytes32[])": { + "notice": "Calculate the root of Merkle tree from an array of power of 2 elements" + }, + "getEmptyTreeHashAtIndex(uint256)": { + "notice": "Gets precomputed hash of zero in empty tree hashes" + }, + "getHashOfWordAtIndex(bytes,uint256)": { + "notice": "Get the hash of a word in an array of bytes" + }, + "getMerkleRootFromBytes(bytes,uint256)": { + "notice": "get merkle root of generic array of bytes" + }, + "getRootAfterReplacementInDrive(uint256,uint256,uint256,bytes32,bytes32[])": { + "notice": "Gets merkle root hash of drive with a replacement" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/MineTimelock.json b/echo-js/deployments/localhost/MineTimelock.json new file mode 100644 index 00000000..c30297b1 --- /dev/null +++ b/echo-js/deployments/localhost/MineTimelock.json @@ -0,0 +1,241 @@ +{ + "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "beneficiary", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "release", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isOwner", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "releaseTime", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "beneficiary", + "type": "address" + } + ], + "name": "changeBeneficiary", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "token", + "type": "address" + }, + { + "name": "beneficiary", + "type": "address" + }, + { + "name": "releaseTime", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "newBeneficiary", + "type": "address" + } + ], + "name": "BeneficiaryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } + ], + "transactionHash": "0xfa8bd2544aee2d5b77458d17bf2a4bce47f51afe1a04f3e9d7e1b9690b094cc8", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + "transactionIndex": 0, + "gasUsed": "907201", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000100000800000000000000000000000000000000400000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000040000000000000000000000000000000008000000000000000200000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7778853881fc64c60f4d7c4030b10c4f9bd8ad9264ad125afc58757c79524bcb", + "transactionHash": "0xfa8bd2544aee2d5b77458d17bf2a4bce47f51afe1a04f3e9d7e1b9690b094cc8", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9, + "transactionHash": "0xfa8bd2544aee2d5b77458d17bf2a4bce47f51afe1a04f3e9d7e1b9690b094cc8", + "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x7778853881fc64c60f4d7c4030b10c4f9bd8ad9264ad125afc58757c79524bcb" + } + ], + "blockNumber": 9, + "cumulativeGasUsed": "907201", + "status": 1, + "byzantium": true + }, + "args": [ + "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + 1761850573 + ], + "numDeployments": 1, + "bytecode": "0x608060405234801561001057600080fd5b50604051606080610fea8339810180604052606081101561003057600080fd5b8101908080519060200190929190805190602001909291908051906020019092919050505060006100656101ee60201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350428111151561015d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180610fb86032913960400191505060405180910390fd5b82600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806003819055505050506101f6565b600033905090565b610db3806102056000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80638f32d59b116100665780638f32d59b14610140578063b91d400114610162578063dc07065714610180578063f2fde38b146101c4578063fc0c546a1461020857610093565b806338af3eed14610098578063715018a6146100e257806386d1a69f146100ec5780638da5cb5b146100f6575b600080fd5b6100a0610252565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100ea61027c565b005b6100f46103b7565b005b6100fe6105bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101486105e8565b604051808215151515815260200191505060405180910390f35b61016a610646565b6040518082815260200191505060405180910390f35b6101c26004803603602081101561019657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610650565b005b610206600480360360208110156101da57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610773565b005b6102106107fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6102846105e8565b15156102f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6003544210151515610414576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180610ce36032913960400191505060405180910390fd5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156104b557600080fd5b505afa1580156104c9573d6000803e3d6000fd5b505050506040513d60208110156104df57600080fd5b8101908080519060200190929190505050905060008111151561054d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610d656023913960400191505060405180910390fd5b6105bc600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108259092919063ffffffff16565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661062a6108f6565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b6000600354905090565b6106586105e8565b15156106cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507feee59a71c694e68368a1cb0d135c448051bbfb12289e6c2223b0ceb100c2321d81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b61077b6105e8565b15156107ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6107f8816108fe565b50565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108f1838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb905060e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610a44565b505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610986576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610d156026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610a638273ffffffffffffffffffffffffffffffffffffffff16610c97565b1515610ad7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e74726163740081525060200191505060405180910390fd5b600060608373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083101515610b285780518252602082019150602081019050602083039250610b03565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610b8a576040519150601f19603f3d011682016040523d82523d6000602084013e610b8f565b606091505b5091509150811515610c09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656481525060200191505060405180910390fd5b600081511115610c9157808060200190516020811015610c2857600080fd5b81019080805190602001909291905050501515610c90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180610d3b602a913960400191505060405180910390fd5b5b50505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015610cd957506000801b8214155b9250505091905056fe546f6b656e54696d656c6f636b3a2063757272656e742074696d65206973206265666f72652072656c656173652074696d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564546f6b656e54696d656c6f636b3a206e6f20746f6b656e7320746f2072656c65617365a165627a7a72305820e80c736d9cc7a31ddb7c6011d3a1955fc95354b7254499eb9f0d549446ba12b20029546f6b656e54696d656c6f636b3a2072656c656173652074696d65206973206265666f72652063757272656e742074696d65", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c80638f32d59b116100665780638f32d59b14610140578063b91d400114610162578063dc07065714610180578063f2fde38b146101c4578063fc0c546a1461020857610093565b806338af3eed14610098578063715018a6146100e257806386d1a69f146100ec5780638da5cb5b146100f6575b600080fd5b6100a0610252565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100ea61027c565b005b6100f46103b7565b005b6100fe6105bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101486105e8565b604051808215151515815260200191505060405180910390f35b61016a610646565b6040518082815260200191505060405180910390f35b6101c26004803603602081101561019657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610650565b005b610206600480360360208110156101da57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610773565b005b6102106107fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6102846105e8565b15156102f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6003544210151515610414576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180610ce36032913960400191505060405180910390fd5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156104b557600080fd5b505afa1580156104c9573d6000803e3d6000fd5b505050506040513d60208110156104df57600080fd5b8101908080519060200190929190505050905060008111151561054d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610d656023913960400191505060405180910390fd5b6105bc600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108259092919063ffffffff16565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661062a6108f6565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b6000600354905090565b6106586105e8565b15156106cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507feee59a71c694e68368a1cb0d135c448051bbfb12289e6c2223b0ceb100c2321d81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b61077b6105e8565b15156107ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6107f8816108fe565b50565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108f1838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb905060e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610a44565b505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610986576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610d156026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610a638273ffffffffffffffffffffffffffffffffffffffff16610c97565b1515610ad7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e74726163740081525060200191505060405180910390fd5b600060608373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083101515610b285780518252602082019150602081019050602083039250610b03565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610b8a576040519150601f19603f3d011682016040523d82523d6000602084013e610b8f565b606091505b5091509150811515610c09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656481525060200191505060405180910390fd5b600081511115610c9157808060200190516020811015610c2857600080fd5b81019080805190602001909291905050501515610c90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180610d3b602a913960400191505060405180910390fd5b5b50505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015610cd957506000801b8214155b9250505091905056fe546f6b656e54696d656c6f636b3a2063757272656e742074696d65206973206265666f72652072656c656173652074696d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564546f6b656e54696d656c6f636b3a206e6f20746f6b656e7320746f2072656c65617365a165627a7a72305820e80c736d9cc7a31ddb7c6011d3a1955fc95354b7254499eb9f0d549446ba12b20029", + "devdoc": { + "details": "A token holder contract that will allow a beneficiary to extract the tokens after a given release time. * Useful for simple vesting schedules like \"advisors get all of their tokens after 1 year\". * For a more complete vesting schedule, see {TokenVesting}.", + "methods": { + "beneficiary()": { + "return": "the beneficiary of the tokens." + }, + "isOwner()": { + "details": "Returns true if the caller is the current owner." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "releaseTime()": { + "return": "the time when the tokens are released." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. * NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "token()": { + "return": "the token being held." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + } + }, + "userdoc": { + "methods": { + "release()": { + "notice": "Transfers tokens held by timelock to beneficiary." + } + } + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/OutputFacet.json b/echo-js/deployments/localhost/OutputFacet.json new file mode 100644 index 00000000..ab913989 --- /dev/null +++ b/echo-js/deployments/localhost/OutputFacet.json @@ -0,0 +1,448 @@ +{ + "address": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "voucherPosition", + "type": "uint256" + } + ], + "name": "VoucherExecuted", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_destination", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "epochIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "outputIndex", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "outputHashesRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vouchersEpochRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "noticesEpochRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "machineStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "keccakInHashesSiblings", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "outputHashesInEpochSiblings", + "type": "bytes32[]" + } + ], + "internalType": "struct OutputValidityProof", + "name": "_v", + "type": "tuple" + } + ], + "name": "executeVoucher", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_voucher", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_input", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_epoch", + "type": "uint256" + } + ], + "name": "getBitMaskPosition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getEpochNoticeLog2Size", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getEpochVoucherLog2Size", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_log2Size", + "type": "uint256" + } + ], + "name": "getIntraDrivePosition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getNoticeMetadataLog2Size", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getNumberOfFinalizedEpochs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVoucherMetadataLog2Size", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_encodedNotice", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "epochIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "outputIndex", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "outputHashesRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vouchersEpochRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "noticesEpochRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "machineStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "keccakInHashesSiblings", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "outputHashesInEpochSiblings", + "type": "bytes32[]" + } + ], + "internalType": "struct OutputValidityProof", + "name": "_v", + "type": "tuple" + } + ], + "name": "isValidNoticeProof", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_encodedVoucher", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "epochIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inputIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "outputIndex", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "outputHashesRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vouchersEpochRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "noticesEpochRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "machineStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "keccakInHashesSiblings", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "outputHashesInEpochSiblings", + "type": "bytes32[]" + } + ], + "internalType": "struct OutputValidityProof", + "name": "_v", + "type": "tuple" + } + ], + "name": "isValidVoucherProof", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x9980a2ee195a304e55ff3e3dfd2ed12cb091da7e8407e0a8b88e5f475b2e03dd", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", + "transactionIndex": 0, + "gasUsed": "742886", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x38d1f26e745def924024fb46857f0a0e6dfbc20ce571ce7455308c916a3b8a74", + "transactionHash": "0x9980a2ee195a304e55ff3e3dfd2ed12cb091da7e8407e0a8b88e5f475b2e03dd", + "logs": [], + "blockNumber": 27, + "cumulativeGasUsed": "742886", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"voucherPosition\",\"type\":\"uint256\"}],\"name\":\"VoucherExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"epochIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inputIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"outputHashesRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"vouchersEpochRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"noticesEpochRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"machineStateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"keccakInHashesSiblings\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"outputHashesInEpochSiblings\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct OutputValidityProof\",\"name\":\"_v\",\"type\":\"tuple\"}],\"name\":\"executeVoucher\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_voucher\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_input\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_epoch\",\"type\":\"uint256\"}],\"name\":\"getBitMaskPosition\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getEpochNoticeLog2Size\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getEpochVoucherLog2Size\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_log2Size\",\"type\":\"uint256\"}],\"name\":\"getIntraDrivePosition\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNoticeMetadataLog2Size\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumberOfFinalizedEpochs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVoucherMetadataLog2Size\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_encodedNotice\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_epochHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"epochIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inputIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"outputHashesRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"vouchersEpochRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"noticesEpochRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"machineStateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"keccakInHashesSiblings\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"outputHashesInEpochSiblings\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct OutputValidityProof\",\"name\":\"_v\",\"type\":\"tuple\"}],\"name\":\"isValidNoticeProof\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_encodedVoucher\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_epochHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"epochIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"inputIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"outputHashesRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"vouchersEpochRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"noticesEpochRootHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"machineStateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"keccakInHashesSiblings\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"outputHashesInEpochSiblings\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct OutputValidityProof\",\"name\":\"_v\",\"type\":\"tuple\"}],\"name\":\"isValidVoucherProof\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"executeVoucher(address,bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))\":{\"details\":\"vouchers can only be executed once\",\"params\":{\"_destination\":\"address that will execute the payload\",\"_payload\":\"payload to be executed by destination\",\"_v\":\"validity proof for this encoded voucher\"},\"returns\":{\"_0\":\"true if voucher was executed successfully\"}},\"getBitMaskPosition(uint256,uint256,uint256)\":{\"params\":{\"_epoch\":\"which epoch the voucher belongs to\",\"_input\":\"which input, inside the epoch, the voucher belongs to\",\"_voucher\":\"of voucher inside the input\"},\"returns\":{\"_0\":\"position of that voucher on bitmask\"}},\"getIntraDrivePosition(uint256,uint256)\":{\"params\":{\"_index\":\"index of intra memory range\",\"_log2Size\":\"of intra memory range\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"executeVoucher(address,bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))\":{\"notice\":\"executes voucher\"},\"getBitMaskPosition(uint256,uint256,uint256)\":{\"notice\":\"get voucher position on bitmask\"},\"getEpochNoticeLog2Size()\":{\"notice\":\"get log2 size of epoch notice memory range\"},\"getEpochVoucherLog2Size()\":{\"notice\":\"get log2 size of epoch voucher memory range\"},\"getNoticeMetadataLog2Size()\":{\"notice\":\"get log2 size of notice metadata memory range\"},\"getNumberOfFinalizedEpochs()\":{\"notice\":\"get number of finalized epochs\"},\"getVoucherMetadataLog2Size()\":{\"notice\":\"get log2 size of voucher metadata memory range\"},\"isValidNoticeProof(bytes,bytes32,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))\":{\"notice\":\"isValidNoticeProof reverts if the proof is invalid\"},\"isValidVoucherProof(bytes,bytes32,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))\":{\"notice\":\"isValidVoucherProof reverts if the proof is invalid\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OutputFacet.sol\":\"OutputFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@cartesi/util/contracts/Bitmask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\npragma solidity ^0.8.0;\\n\\n/// @title Bit Mask Library\\n/// @author Stephen Chen\\n/// @notice Implements bit mask with dynamic array\\nlibrary Bitmask {\\n /// @notice Set a bit in the bit mask\\n function setBit(\\n mapping(uint256 => uint256) storage bitmask,\\n uint256 _bit,\\n bool _value\\n ) public {\\n // calculate the number of bits has been store in bitmask now\\n uint256 positionOfMask = uint256(_bit / 256);\\n uint256 positionOfBit = _bit % 256;\\n\\n if (_value) {\\n bitmask[positionOfMask] =\\n bitmask[positionOfMask] |\\n (1 << positionOfBit);\\n } else {\\n bitmask[positionOfMask] =\\n bitmask[positionOfMask] &\\n ~(1 << positionOfBit);\\n }\\n }\\n\\n /// @notice Get a bit in the bit mask\\n function getBit(mapping(uint256 => uint256) storage bitmask, uint256 _bit)\\n public\\n view\\n returns (bool)\\n {\\n // calculate the number of bits has been store in bitmask now\\n uint256 positionOfMask = uint256(_bit / 256);\\n uint256 positionOfBit = _bit % 256;\\n\\n return ((bitmask[positionOfMask] & (1 << positionOfBit)) != 0);\\n }\\n}\\n\",\"keccak256\":\"0xe35cf68672f5844589c0e56f36aa3813ca4ffb882a55a46d15adac7e3cc889bd\",\"license\":\"Apache-2.0\"},\"@cartesi/util/contracts/CartesiMath.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title CartesiMath\\n/// @author Felipe Argento\\npragma solidity ^0.8.0;\\n\\nlibrary CartesiMath {\\n // mapping values are packed as bytes3 each\\n // see test/TestCartesiMath.ts for decimal values\\n bytes constant log2tableTimes1M =\\n hex\\\"0000000F4240182F421E8480236E082771822AD63A2DC6C0305E8532B04834C96736B3C23876D73A187A3B9D4A3D09003E5EA63FA0C540D17741F28843057D440BA745062945F60246DC1047B917488DC7495ABA4A207C4ADF8A4B98544C4B404CF8AA4DA0E64E44434EE3054F7D6D5013B750A61A5134C851BFF05247BD52CC58534DE753CC8D54486954C19C55384255AC75561E50568DE956FB575766B057D00758376F589CFA5900BA5962BC59C3135A21CA5A7EF15ADA945B34BF5B8D805BE4DF5C3AEA5C8FA95CE3265D356C5D86835DD6735E25455E73005EBFAD5F0B525F55F75F9FA25FE85A60302460770860BD0A61023061467F6189FD61CCAE620E98624FBF62902762CFD5630ECD634D12638AA963C7966403DC643F7F647A8264B4E864EEB56527EC6560906598A365D029660724663D9766738566A8F066DDDA6712476746386779AF67ACAF67DF3A6811526842FA68743268A4FC68D55C6905536934E169640A6992CF69C13169EF326A1CD46A4A186A76FF6AA38C6ACFC0\\\";\\n\\n /// @notice Approximates log2 * 1M\\n /// @param _num number to take log2 * 1M of\\n /// @return approximate log2 times 1M\\n function log2ApproxTimes1M(uint256 _num) public pure returns (uint256) {\\n require(_num > 0, \\\"Number cannot be zero\\\");\\n uint256 leading = 0;\\n\\n if (_num == 1) return 0;\\n\\n while (_num > 128) {\\n _num = _num >> 1;\\n leading += 1;\\n }\\n return (leading * uint256(1000000)) + (getLog2TableTimes1M(_num));\\n }\\n\\n /// @notice navigates log2tableTimes1M\\n /// @param _num number to take log2 of\\n /// @return result after table look-up\\n function getLog2TableTimes1M(uint256 _num) public pure returns (uint256) {\\n bytes3 result = 0;\\n for (uint8 i = 0; i < 3; i++) {\\n bytes3 tempResult = log2tableTimes1M[(_num - 1) * 3 + i];\\n result = result | (tempResult >> (i * 8));\\n }\\n\\n return uint256(uint24(result));\\n }\\n\\n /// @notice get floor of log2 of number\\n /// @param _num number to take floor(log2) of\\n /// @return floor(log2) of _num\\n function getLog2Floor(uint256 _num) public pure returns (uint8) {\\n require(_num != 0, \\\"log of zero is undefined\\\");\\n\\n return uint8(255 - clz(_num));\\n }\\n\\n /// @notice checks if a number is Power of 2\\n /// @param _num number to check\\n /// @return true if number is power of 2, false if not\\n function isPowerOf2(uint256 _num) public pure returns (bool) {\\n if (_num == 0) return false;\\n\\n return _num & (_num - 1) == 0;\\n }\\n\\n /// @notice count trailing zeros\\n /// @param _num number you want the ctz of\\n /// @dev this a binary search implementation\\n function ctz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { n = n + 128; _num = _num >> 128; }\\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) { n = n + 64; _num = _num >> 64; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) { n = n + 32; _num = _num >> 32; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) { n = n + 16; _num = _num >> 16; }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) { n = n + 8; _num = _num >> 8; }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) { n = n + 4; _num = _num >> 4; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) { n = n + 2; _num = _num >> 2; }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n\\n /// @notice count leading zeros\\n /// @param _num number you want the clz of\\n /// @dev this a binary search implementation\\n function clz(uint256 _num) public pure returns (uint256) {\\n if (_num == 0) return 256;\\n\\n uint256 n = 0;\\n if (_num & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 == 0) { n = n + 128; _num = _num << 128; }\\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) { n = n + 64; _num = _num << 64; }\\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) { n = n + 32; _num = _num << 32; }\\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 16; _num = _num << 16; }\\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 8; _num = _num << 8; }\\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 4; _num = _num << 4; }\\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 2; _num = _num << 2; }\\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 1; }\\n\\n return n;\\n }\\n}\\n\",\"keccak256\":\"0x28b74012e966438edff701decdc5ffd207b3f0244af65fbd7d397050986e58d4\",\"license\":\"Apache-2.0\"},\"@cartesi/util/contracts/Merkle.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Library for Merkle proofs\\npragma solidity ^0.8.0;\\n\\nimport \\\"./CartesiMath.sol\\\";\\n\\nlibrary Merkle {\\n using CartesiMath for uint256;\\n\\n uint128 constant L_WORD_SIZE = 3; // word = 8 bytes, log = 3\\n // number of hashes in EMPTY_TREE_HASHES\\n uint128 constant EMPTY_TREE_SIZE = 1952; // 61*32=1952. 32 bytes per 61 indexes (64 words)\\n\\n // merkle root hashes of trees of zero concatenated\\n // 32 bytes for each root, first one is keccak(0), second one is\\n // keccak(keccack(0), keccak(0)) and so on\\n\\n bytes constant EMPTY_TREE_HASHES =\\n hex\\\"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce4d9470a821fbe90117ec357e30bad9305732fb19ddf54a07dd3e29f440619254ae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a233fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9c37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e68e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e30930b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90cd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efed8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0c9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e6163e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b72122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046f7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec517a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca892b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e152499af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f27d86025599a41233848702f0cfc0437b445682df51147a632a0a083d2d38b5e13e466a8935afff58bb533b3ef5d27fba63ee6b0fd9e67ff20af9d50deee3f8bf065ec220c1fd4ba57e341261d55997f85d66d32152526736872693d2b437a233e2337b715f6ac9a6a272622fdc2d67fcfe1da3459f8dab4ed7e40a657a54c36766c5e8ac9a88b35b05c34747e6507f6b044ab66180dc76ac1a696de03189593fedc0d0dbbd855c8ead673544899b0960e4a5a7ca43b4ef90afe607de7698caefdc242788f654b57a4fb32a71b335ef6ff9a4cc118b282b53bdd6d6192b7a82c3c5126b9c7e33c8e5a5ac9738b8bd31247fb7402054f97b573e8abb9faad219f4fd085aceaa7f542d787ee4196d365f3cc566e7bbcfbfd451230c48d804c017d21e2d8fa914e2559bb72bf0ab78c8ab92f00ef0d0d576eccdd486b64138a4172674857e543d1d5b639058dd908186597e366ad5f3d9c7ceaff44d04d1550b8d33abc751df07437834ba5acb32328a396994aebb3c40f759c2d6d7a3cb5377e55d5d218ef5a296dda8ddc355f3f50c3d0b660a51dfa4d98a6a5a33564556cf83c1373a814641d6a1dcef97b883fee61bb84fe60a3409340217e629cc7e4dcc93b85d8820921ff5826148b60e6939acd7838e1d7f20562bff8ee4b5ec4a05ad997a57b9796fdcb2eda87883c2640b072b140b946bfdf6575cacc066fdae04f6951e63624cbd316a677cad529bbe4e97b9144e4bc06c4afd1de55dd3e1175f90423847a230d34dfb71ed56f2965a7f6c72e6aa33c24c303fd67745d632656c5ef90bec80f4f5d1daa251988826cef375c81c36bf457e09687056f924677cb0bccf98dff81e014ce25f2d132497923e267363963cdf4302c5049d63131dc03fd95f65d8b6aa5934f817252c028c90f56d413b9d5d10d89790707dae2fabb249f649929927c21dd71e3f656826de5451c5da375aadecbd59d5ebf3a31fae65ac1b316a1611f1b276b26530f58d7247df459ce1f86db1d734f6f811932f042cee45d0e455306d01081bc3384f82c5fb2aacaa19d89cdfa46cc916eac61121475ba2e6191b4feecbe1789717021a158ace5d06744b40f551076b67cd63af60007f8c99876e1424883a45ec49d497ddaf808a5521ca74a999ab0b3c7aa9c80f85e93977ec61ce68b20307a1a81f71ca645b568fcd319ccbb5f651e87b707d37c39e15f945ea69e2f7c7d2ccc85b7e654c07e96f0636ae4044fe0e38590b431795ad0f8647bdd613713ada493cc17efd313206380e6a685b8198475bbd021c6e9d94daab2214947127506073e44d5408ba166c512a0b86805d07f5a44d3c41706be2bc15e712e55805248b92e8677d90f6d284d1d6ffaff2c430657042a0e82624fa3717b06cc0a6fd12230ea586dae83019fb9e06034ed2803c98d554b93c9a52348cafff75c40174a91f9ae6b8647854a156029f0b88b83316663ce574a4978277bb6bb27a31085634b6ec78864b6d8201c7e93903d75815067e378289a3d072ae172dafa6a452470f8d645bebfad9779594fc0784bb764a22e3a8181d93db7bf97893c414217a618ccb14caa9e92e8c61673afc9583662e812adba1f87a9c68202d60e909efab43c42c0cb00695fc7f1ffe67c75ca894c3c51e1e5e731360199e600f6ced9a87b2a6a87e70bf251bb5075ab222138288164b2eda727515ea7de12e2496d4fe42ea8d1a120c03cf9c50622c2afe4acb0dad98fd62d07ab4e828a94495f6d1ab973982c7ccbe6c1fae02788e4422ae22282fa49cbdb04ba54a7a238c6fc41187451383460762c06d1c8a72b9cd718866ad4b689e10c9a8c38fe5ef045bd785b01e980fc82c7e3532ce81876b778dd9f1ceeba4478e86411fb6fdd790683916ca832592485093644e8760cd7b4c01dba1ccc82b661bf13f0e3f34acd6b88\\\";\\n\\n /// @notice Gets merkle root hash of drive with a replacement\\n /// @param _position position of _drive\\n /// @param _logSizeOfReplacement log2 of size the replacement\\n /// @param _logSizeOfFullDrive log2 of size the full drive, which can be the entire machine\\n /// @param _replacement hash of the replacement\\n /// @param siblings of replacement that merkle root can be calculated\\n function getRootAfterReplacementInDrive(\\n uint256 _position,\\n uint256 _logSizeOfReplacement,\\n uint256 _logSizeOfFullDrive,\\n bytes32 _replacement,\\n bytes32[] calldata siblings\\n ) public pure returns (bytes32) {\\n require(\\n _logSizeOfFullDrive >= _logSizeOfReplacement &&\\n _logSizeOfReplacement >= 3 &&\\n _logSizeOfFullDrive <= 64,\\n \\\"3 <= logSizeOfReplacement <= logSizeOfFullDrive <= 64\\\"\\n );\\n\\n uint256 size = 1 << _logSizeOfReplacement;\\n\\n require(((size - 1) & _position) == 0, \\\"Position is not aligned\\\");\\n require(\\n siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement,\\n \\\"Proof length does not match\\\"\\n );\\n\\n for (uint256 i; i < siblings.length; i++) {\\n if ((_position & (size << i)) == 0) {\\n _replacement = keccak256(\\n abi.encodePacked(_replacement, siblings[i])\\n );\\n } else {\\n _replacement = keccak256(\\n abi.encodePacked(siblings[i], _replacement)\\n );\\n }\\n }\\n\\n return _replacement;\\n }\\n\\n /// @notice Gets precomputed hash of zero in empty tree hashes\\n /// @param _index of hash wanted\\n /// @dev first index is keccak(0), second index is keccak(keccak(0), keccak(0))\\n function getEmptyTreeHashAtIndex(uint256 _index)\\n public\\n pure\\n returns (bytes32)\\n {\\n uint256 start = _index * 32;\\n require(EMPTY_TREE_SIZE >= start + 32, \\\"index out of bounds\\\");\\n bytes32 hashedZeros;\\n bytes memory zeroTree = EMPTY_TREE_HASHES;\\n\\n // first word is length, then skip index words\\n assembly {\\n hashedZeros := mload(add(add(zeroTree, 0x20), start))\\n }\\n return hashedZeros;\\n }\\n\\n /// @notice get merkle root of generic array of bytes\\n /// @param _data array of bytes to be merklelized\\n /// @param _log2Size log2 of total size of the drive\\n /// @dev _data is padded with zeroes until is multiple of 8\\n /// @dev root is completed with zero tree until log2size is complete\\n /// @dev hashes are taken word by word (8 bytes by 8 bytes)\\n function getMerkleRootFromBytes(bytes calldata _data, uint256 _log2Size)\\n public\\n pure\\n returns (bytes32)\\n {\\n require(_log2Size >= 3 && _log2Size <= 64, \\\"range of log2Size: [3,64]\\\");\\n\\n // if _data is empty return pristine drive of size log2size\\n if (_data.length == 0) return getEmptyTreeHashAtIndex(_log2Size - 3);\\n\\n // total size of the drive in words\\n uint256 size = 1 << (_log2Size - 3);\\n require(\\n size << L_WORD_SIZE >= _data.length,\\n \\\"data is bigger than drive\\\"\\n );\\n // the stack depth is log2(_data.length / 8) + 2\\n uint256 stack_depth = 2 +\\n ((_data.length) >> L_WORD_SIZE).getLog2Floor();\\n bytes32[] memory stack = new bytes32[](stack_depth);\\n\\n uint256 numOfHashes; // total number of hashes on stack (counting levels)\\n uint256 stackLength; // total length of stack\\n uint256 numOfJoins; // number of hashes of the same level on stack\\n uint256 topStackLevel; // hash level of the top of the stack\\n\\n while (numOfHashes < size) {\\n if ((numOfHashes << L_WORD_SIZE) < _data.length) {\\n // we still have words to hash\\n stack[stackLength] = getHashOfWordAtIndex(_data, numOfHashes);\\n numOfHashes++;\\n\\n numOfJoins = numOfHashes;\\n } else {\\n // since padding happens in hashOfWordAtIndex function\\n // we only need to complete the stack with pre-computed\\n // hash(0), hash(hash(0),hash(0)) and so on\\n topStackLevel = numOfHashes.ctz();\\n\\n stack[stackLength] = getEmptyTreeHashAtIndex(topStackLevel);\\n\\n //Empty Tree Hash summarizes many hashes\\n numOfHashes = numOfHashes + (1 << topStackLevel);\\n numOfJoins = numOfHashes >> topStackLevel;\\n }\\n\\n stackLength++;\\n\\n // while there are joins, hash top of stack together\\n while (numOfJoins & 1 == 0) {\\n bytes32 h2 = stack[stackLength - 1];\\n bytes32 h1 = stack[stackLength - 2];\\n\\n stack[stackLength - 2] = keccak256(abi.encodePacked(h1, h2));\\n stackLength = stackLength - 1; // remove hashes from stack\\n\\n numOfJoins = numOfJoins >> 1;\\n }\\n }\\n require(stackLength == 1, \\\"stack error\\\");\\n\\n return stack[0];\\n }\\n\\n /// @notice Get the hash of a word in an array of bytes\\n /// @param _data array of bytes\\n /// @param _wordIndex index of word inside the bytes to get the hash of\\n /// @dev if word is incomplete (< 8 bytes) it gets padded with zeroes\\n function getHashOfWordAtIndex(bytes calldata _data, uint256 _wordIndex)\\n public\\n pure\\n returns (bytes32)\\n {\\n uint256 start = _wordIndex << L_WORD_SIZE;\\n uint256 end = start + (1 << L_WORD_SIZE);\\n\\n // TODO: in .lua this just returns zero, but this might be more consistent\\n require(start <= _data.length, \\\"word out of bounds\\\");\\n\\n if (end <= _data.length) {\\n return keccak256(abi.encodePacked(_data[start:end]));\\n }\\n\\n // word is incomplete\\n // fill paddedSlice with incomplete words - the rest is going to be bytes(0)\\n bytes memory paddedSlice = new bytes(8);\\n uint256 remaining = _data.length - start;\\n\\n for (uint256 i; i < remaining; i++) {\\n paddedSlice[i] = _data[start + i];\\n }\\n\\n return keccak256(paddedSlice);\\n }\\n\\n /// @notice Calculate the root of Merkle tree from an array of power of 2 elements\\n /// @param hashes The array containing power of 2 elements\\n /// @return byte32 the root hash being calculated\\n function calculateRootFromPowerOfTwo(bytes32[] memory hashes)\\n public\\n pure\\n returns (bytes32)\\n {\\n // revert when the input is not of power of 2\\n require((hashes.length).isPowerOf2(), \\\"array len not power of 2\\\");\\n\\n if (hashes.length == 1) {\\n return hashes[0];\\n } else {\\n bytes32[] memory newHashes = new bytes32[](hashes.length >> 1);\\n\\n for (uint256 i; i < hashes.length; i += 2) {\\n newHashes[i >> 1] = keccak256(\\n abi.encodePacked(hashes[i], hashes[i + 1])\\n );\\n }\\n\\n return calculateRootFromPowerOfTwo(newHashes);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe9896db44cc4dab335a3e776c629186824823d316d902b2efecb4b0a3e3dfdb7\",\"license\":\"Apache-2.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/OutputFacet.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output facet\\npragma solidity ^0.8.0;\\n\\nimport {Bitmask} from \\\"@cartesi/util/contracts/Bitmask.sol\\\";\\nimport {Merkle} from \\\"@cartesi/util/contracts/Merkle.sol\\\";\\n\\nimport {IOutput, OutputValidityProof} from \\\"../interfaces/IOutput.sol\\\";\\n\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\ncontract OutputFacet is IOutput {\\n using LibOutput for LibOutput.DiamondStorage;\\n\\n // Here we only need 248 bits as keys in the mapping, but we use 256 bits for gas optimization\\n using Bitmask for mapping(uint256 => uint256);\\n\\n uint256 constant KECCAK_LOG2_SIZE = 5; // keccak log2 size\\n\\n // max size of voucher metadata memory range 32 * (2^16) bytes\\n uint256 constant VOUCHER_METADATA_LOG2_SIZE = 21;\\n // max size of epoch voucher memory range 32 * (2^32) bytes\\n uint256 constant EPOCH_VOUCHER_LOG2_SIZE = 37;\\n\\n // max size of notice metadata memory range 32 * (2^16) bytes\\n uint256 constant NOTICE_METADATA_LOG2_SIZE = 21;\\n // max size of epoch notice memory range 32 * (2^32) bytes\\n uint256 constant EPOCH_NOTICE_LOG2_SIZE = 37;\\n\\n /// @notice functions modified by noReentrancy are not subject to recursion\\n modifier noReentrancy() {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n require(!outputDS.lock, \\\"reentrancy not allowed\\\");\\n outputDS.lock = true;\\n _;\\n outputDS.lock = false;\\n }\\n\\n /// @notice executes voucher\\n /// @param _destination address that will execute the payload\\n /// @param _payload payload to be executed by destination\\n /// @param _v validity proof for this encoded voucher\\n /// @return true if voucher was executed successfully\\n /// @dev vouchers can only be executed once\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n OutputValidityProof calldata _v\\n ) public override noReentrancy returns (bool) {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n\\n // avoid a malicious DApp developer from draining the Fee Manager's bank account\\n require(_destination != address(feeManagerDS.bank), \\\"bad destination\\\");\\n\\n bytes memory encodedVoucher = abi.encode(_destination, _payload);\\n\\n // check if validity proof matches the voucher provided\\n isValidVoucherProof(\\n encodedVoucher,\\n outputDS.epochHashes[_v.epochIndex],\\n _v\\n );\\n\\n uint256 voucherPosition = getBitMaskPosition(\\n _v.outputIndex,\\n _v.inputIndex,\\n _v.epochIndex\\n );\\n\\n // check if voucher has been executed\\n require(\\n !outputDS.voucherBitmask.getBit(voucherPosition),\\n \\\"re-execution not allowed\\\"\\n );\\n\\n // execute voucher\\n (bool succ, ) = _destination.call(_payload);\\n\\n // if properly executed, mark it as executed and emit event\\n if (succ) {\\n outputDS.voucherBitmask.setBit(voucherPosition, true);\\n emit VoucherExecuted(voucherPosition);\\n }\\n\\n return succ;\\n }\\n\\n /// @notice isValidProof reverts if the proof is invalid\\n /// @dev _outputsEpochRootHash must be _v.vouchersEpochRootHash or\\n /// or _v.noticesEpochRootHash\\n function isValidProof(\\n bytes memory _encodedOutput,\\n bytes32 _epochHash,\\n bytes32 _outputsEpochRootHash,\\n uint256 _outputEpochLog2Size,\\n uint256 _outputHashesLog2Size,\\n OutputValidityProof calldata _v\\n ) internal pure {\\n // prove that outputs hash is represented in a finalized epoch\\n require(\\n keccak256(\\n abi.encodePacked(\\n _v.vouchersEpochRootHash,\\n _v.noticesEpochRootHash,\\n _v.machineStateHash\\n )\\n ) == _epochHash,\\n \\\"epochHash incorrect\\\"\\n );\\n\\n // prove that output metadata memory range is contained in epoch's output memory range\\n require(\\n Merkle.getRootAfterReplacementInDrive(\\n getIntraDrivePosition(_v.inputIndex, KECCAK_LOG2_SIZE),\\n KECCAK_LOG2_SIZE,\\n _outputEpochLog2Size,\\n keccak256(abi.encodePacked(_v.outputHashesRootHash)),\\n _v.outputHashesInEpochSiblings\\n ) == _outputsEpochRootHash,\\n \\\"outputsEpochRootHash incorrect\\\"\\n );\\n\\n // The hash of the output is converted to bytes (abi.encode) and\\n // treated as data. The metadata output memory range stores that data while\\n // being indifferent to its contents. To prove that the received\\n // output is contained in the metadata output memory range we need to\\n // prove that x, where:\\n // x = keccak(\\n // keccak(\\n // keccak(hashOfOutput[0:7]),\\n // keccak(hashOfOutput[8:15])\\n // ),\\n // keccak(\\n // keccak(hashOfOutput[16:23]),\\n // keccak(hashOfOutput[24:31])\\n // )\\n // )\\n // is contained in it. We can't simply use hashOfOutput because the\\n // log2size of the leaf is three (8 bytes) not five (32 bytes)\\n bytes32 merkleRootOfHashOfOutput = Merkle.getMerkleRootFromBytes(\\n abi.encodePacked(keccak256(_encodedOutput)),\\n KECCAK_LOG2_SIZE\\n );\\n\\n // prove that merkle root hash of bytes(hashOfOutput) is contained\\n // in the output metadata array memory range\\n require(\\n Merkle.getRootAfterReplacementInDrive(\\n getIntraDrivePosition(_v.outputIndex, KECCAK_LOG2_SIZE),\\n KECCAK_LOG2_SIZE,\\n _outputHashesLog2Size,\\n merkleRootOfHashOfOutput,\\n _v.keccakInHashesSiblings\\n ) == _v.outputHashesRootHash,\\n \\\"outputHashesRootHash incorrect\\\"\\n );\\n }\\n\\n /// @notice isValidVoucherProof reverts if the proof is invalid\\n function isValidVoucherProof(\\n bytes memory _encodedVoucher,\\n bytes32 _epochHash,\\n OutputValidityProof calldata _v\\n ) public pure {\\n isValidProof(\\n _encodedVoucher,\\n _epochHash,\\n _v.vouchersEpochRootHash,\\n EPOCH_VOUCHER_LOG2_SIZE,\\n VOUCHER_METADATA_LOG2_SIZE,\\n _v\\n );\\n }\\n\\n /// @notice isValidNoticeProof reverts if the proof is invalid\\n function isValidNoticeProof(\\n bytes memory _encodedNotice,\\n bytes32 _epochHash,\\n OutputValidityProof calldata _v\\n ) public pure {\\n isValidProof(\\n _encodedNotice,\\n _epochHash,\\n _v.noticesEpochRootHash,\\n EPOCH_NOTICE_LOG2_SIZE,\\n NOTICE_METADATA_LOG2_SIZE,\\n _v\\n );\\n }\\n\\n /// @notice get voucher position on bitmask\\n /// @param _voucher of voucher inside the input\\n /// @param _input which input, inside the epoch, the voucher belongs to\\n /// @param _epoch which epoch the voucher belongs to\\n /// @return position of that voucher on bitmask\\n function getBitMaskPosition(\\n uint256 _voucher,\\n uint256 _input,\\n uint256 _epoch\\n ) public pure returns (uint256) {\\n // voucher * 2 ** 128 + input * 2 ** 64 + epoch\\n // this can't overflow because its impossible to have > 2**128 vouchers\\n return (((_voucher << 128) | (_input << 64)) | _epoch);\\n }\\n\\n /// @notice returns the position of a intra memory range on a memory range\\n // with contents with the same size\\n /// @param _index index of intra memory range\\n /// @param _log2Size of intra memory range\\n function getIntraDrivePosition(uint256 _index, uint256 _log2Size)\\n public\\n pure\\n returns (uint256)\\n {\\n return (_index << _log2Size);\\n }\\n\\n /// @notice get number of finalized epochs\\n function getNumberOfFinalizedEpochs()\\n public\\n view\\n override\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n return outputDS.getNumberOfFinalizedEpochs();\\n }\\n\\n /// @notice get log2 size of voucher metadata memory range\\n function getVoucherMetadataLog2Size()\\n public\\n pure\\n override\\n returns (uint256)\\n {\\n return VOUCHER_METADATA_LOG2_SIZE;\\n }\\n\\n /// @notice get log2 size of epoch voucher memory range\\n function getEpochVoucherLog2Size() public pure override returns (uint256) {\\n return EPOCH_VOUCHER_LOG2_SIZE;\\n }\\n\\n /// @notice get log2 size of notice metadata memory range\\n function getNoticeMetadataLog2Size()\\n public\\n pure\\n override\\n returns (uint256)\\n {\\n return NOTICE_METADATA_LOG2_SIZE;\\n }\\n\\n /// @notice get log2 size of epoch notice memory range\\n function getEpochNoticeLog2Size() public pure override returns (uint256) {\\n return EPOCH_NOTICE_LOG2_SIZE;\\n }\\n}\\n\",\"keccak256\":\"0x58671cc25ce982551e78e4d6c87de5592ccc691d6a4158ff71c5c004ba76f69f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IOutput.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output interface\\npragma solidity >=0.7.0;\\n\\n/// @param epochIndex which epoch the output belongs to\\n/// @param inputIndex which input, inside the epoch, the output belongs to\\n/// @param outputIndex index of output inside the input\\n/// @param outputHashesRootHash merkle root of all epoch's output metadata hashes\\n/// @param vouchersEpochRootHash merkle root of all epoch's voucher metadata hashes\\n/// @param noticesEpochRootHash merkle root of all epoch's notice metadata hashes\\n/// @param machineStateHash hash of the machine state claimed this epoch\\n/// @param keccakInHashesSiblings proof that this output metadata is in metadata memory range\\n/// @param outputHashesInEpochSiblings proof that this output metadata is in epoch's output memory range\\nstruct OutputValidityProof {\\n uint256 epochIndex;\\n uint256 inputIndex;\\n uint256 outputIndex;\\n bytes32 outputHashesRootHash;\\n bytes32 vouchersEpochRootHash;\\n bytes32 noticesEpochRootHash;\\n bytes32 machineStateHash;\\n bytes32[] keccakInHashesSiblings;\\n bytes32[] outputHashesInEpochSiblings;\\n}\\n\\ninterface IOutput {\\n /// @notice executes voucher\\n /// @param _destination address that will execute the payload\\n /// @param _payload payload to be executed by destination\\n /// @param _v validity proof for this encoded voucher\\n /// @return true if voucher was executed successfully\\n /// @dev vouchers can only be executed once\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n OutputValidityProof calldata _v\\n ) external returns (bool);\\n\\n /// @notice get number of finalized epochs\\n function getNumberOfFinalizedEpochs() external view returns (uint256);\\n\\n /// @notice get log2 size of voucher metadata memory range\\n function getVoucherMetadataLog2Size() external pure returns (uint256);\\n\\n /// @notice get log2 size of epoch voucher memory range\\n function getEpochVoucherLog2Size() external pure returns (uint256);\\n\\n /// @notice get log2 size of notice metadata memory range\\n function getNoticeMetadataLog2Size() external pure returns (uint256);\\n\\n /// @notice get log2 size of epoch notice memory range\\n function getEpochNoticeLog2Size() external pure returns (uint256);\\n\\n event VoucherExecuted(uint256 voucherPosition);\\n}\\n\",\"keccak256\":\"0x79a74b11ae72d4b8eea3c977f3f139b4b976c1a09029968e7c5d326c65286a3e\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610c7b806100206000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80638021be81116100665780638021be811461013557806383552b4d1461013c578063a238203614610163578063a981588a14610135578063f3af7efd1461016357600080fd5b806310517cfc146100a35780633ad58a27146100c85780633c0d9958146100dd5780635e439a0c146100ff5780636190d81e14610112575b600080fd5b6100b56100b1366004610886565b1b90565b6040519081526020015b60405180910390f35b6100db6100d63660046108d7565b61016a565b005b6100b56100eb3660046109b6565b608083901b604083901b1781179392505050565b6100db61010d3660046108d7565b610183565b6101256101203660046109e2565b610197565b60405190151581526020016100bf565b60156100b5565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea567546100b5565b60256100b5565b61017e83838360a00135602560158661055c565b505050565b61017e83838360800135602560158661055c565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea568546000907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060ff161561022c5760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff1916600117905560006102647f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56690565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75549091507f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73906001600160a01b03908116908916036102f85760405162461bcd60e51b815260206004820152600f60248201526e3130b2103232b9ba34b730ba34b7b760891b6044820152606401610223565b600088888860405160200161030f93929190610a98565b604051602081830303815290604052905061034e818460010188600001358154811061033d5761033d610ad8565b906000526020600020015488610183565b60006020870135604090811b9088013560801b178735176040516303fbaf7360e01b8152600481018690526024810182905290915073e7f1725E7734CE288F8367e1Bb143E90bb3F0512906303fbaf7390604401602060405180830381865af41580156103bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e39190610aee565b156104305760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f77656400000000000000006044820152606401610223565b60008a6001600160a01b03168a8a60405161044c929190610b17565b6000604051808303816000865af19150503d8060008114610489576040519150601f19603f3d011682016040523d82523d6000602084013e61048e565b606091505b505090508015610543576040516306449da160e41b815260048101869052602481018390526001604482015273e7f1725E7734CE288F8367e1Bb143E90bb3F051290636449da109060640160006040518083038186803b1580156104f157600080fd5b505af4158015610505573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc548260405161053a91815260200190565b60405180910390a15b955050505050600201805460ff19169055949350505050565b60408051608080840135602083015260a08401359282019290925260c0830135606082015286910160405160208183030381529060405280519060200120146105dd5760405162461bcd60e51b8152602060048201526013602482015272195c1bd8da12185cda081a5b98dbdc9c9958dd606a1b6044820152606401610223565b8373Cf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc96379de4601602084013560051b600587866060013560405160200161061a91815260200190565b60408051601f198184030181529190528051602090910120610640610100890189610b27565b6040518763ffffffff1660e01b815260040161066196959493929190610b78565b602060405180830381865af415801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a29190610bcf565b146106ef5760405162461bcd60e51b815260206004820152601e60248201527f6f75747075747345706f6368526f6f744861736820696e636f727265637400006044820152606401610223565b600073Cf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc963c84583a1888051906020012060405160200161072591815260200190565b60405160208183030381529060405260056040518363ffffffff1660e01b8152600401610753929190610be8565b602060405180830381865af4158015610770573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107949190610bcf565b9050606082013573Cf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc96379de4601604085013560051b600587866107ce60e08a018a610b27565b6040518763ffffffff1660e01b81526004016107ef96959493929190610b78565b602060405180830381865af415801561080c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108309190610bcf565b1461087d5760405162461bcd60e51b815260206004820152601e60248201527f6f7574707574486173686573526f6f744861736820696e636f727265637400006044820152606401610223565b50505050505050565b6000806040838503121561089957600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600061012082840312156108d157600080fd5b50919050565b6000806000606084860312156108ec57600080fd5b833567ffffffffffffffff8082111561090457600080fd5b818601915086601f83011261091857600080fd5b81358181111561092a5761092a6108a8565b604051601f8201601f19908116603f01168101908382118183101715610952576109526108a8565b8160405282815289602084870101111561096b57600080fd5b8260208601602083013760006020848301015280975050505060208601359350604086013591508082111561099f57600080fd5b506109ac868287016108be565b9150509250925092565b6000806000606084860312156109cb57600080fd5b505081359360208301359350604090920135919050565b600080600080606085870312156109f857600080fd5b84356001600160a01b0381168114610a0f57600080fd5b9350602085013567ffffffffffffffff80821115610a2c57600080fd5b818701915087601f830112610a4057600080fd5b813581811115610a4f57600080fd5b886020828501011115610a6157600080fd5b602083019550809450506040870135915080821115610a7f57600080fd5b50610a8c878288016108be565b91505092959194509250565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610b0057600080fd5b81518015158114610b1057600080fd5b9392505050565b8183823760009101908152919050565b6000808335601e19843603018112610b3e57600080fd5b83018035915067ffffffffffffffff821115610b5957600080fd5b6020019150600581901b3603821315610b7157600080fd5b9250929050565b86815285602082015284604082015283606082015260a060808201528160a0820152600060018060fb1b03831115610baf57600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b600060208284031215610be157600080fd5b5051919050565b604081526000835180604084015260005b81811015610c165760208187018101516060868401015201610bf9565b81811115610c28576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fea2646970667358221220466e987a6ad69c9b9648327f0c965f4c05297bb68be7c1491af5e8f2fc075ca064736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c80638021be81116100665780638021be811461013557806383552b4d1461013c578063a238203614610163578063a981588a14610135578063f3af7efd1461016357600080fd5b806310517cfc146100a35780633ad58a27146100c85780633c0d9958146100dd5780635e439a0c146100ff5780636190d81e14610112575b600080fd5b6100b56100b1366004610886565b1b90565b6040519081526020015b60405180910390f35b6100db6100d63660046108d7565b61016a565b005b6100b56100eb3660046109b6565b608083901b604083901b1781179392505050565b6100db61010d3660046108d7565b610183565b6101256101203660046109e2565b610197565b60405190151581526020016100bf565b60156100b5565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea567546100b5565b60256100b5565b61017e83838360a00135602560158661055c565b505050565b61017e83838360800135602560158661055c565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea568546000907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060ff161561022c5760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff1916600117905560006102647f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56690565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75549091507f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73906001600160a01b03908116908916036102f85760405162461bcd60e51b815260206004820152600f60248201526e3130b2103232b9ba34b730ba34b7b760891b6044820152606401610223565b600088888860405160200161030f93929190610a98565b604051602081830303815290604052905061034e818460010188600001358154811061033d5761033d610ad8565b906000526020600020015488610183565b60006020870135604090811b9088013560801b178735176040516303fbaf7360e01b8152600481018690526024810182905290915073__$f57eb21c11c6dae369da3ca36f4f48eb77$__906303fbaf7390604401602060405180830381865af41580156103bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e39190610aee565b156104305760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f77656400000000000000006044820152606401610223565b60008a6001600160a01b03168a8a60405161044c929190610b17565b6000604051808303816000865af19150503d8060008114610489576040519150601f19603f3d011682016040523d82523d6000602084013e61048e565b606091505b505090508015610543576040516306449da160e41b815260048101869052602481018390526001604482015273__$f57eb21c11c6dae369da3ca36f4f48eb77$__90636449da109060640160006040518083038186803b1580156104f157600080fd5b505af4158015610505573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc548260405161053a91815260200190565b60405180910390a15b955050505050600201805460ff19169055949350505050565b60408051608080840135602083015260a08401359282019290925260c0830135606082015286910160405160208183030381529060405280519060200120146105dd5760405162461bcd60e51b8152602060048201526013602482015272195c1bd8da12185cda081a5b98dbdc9c9958dd606a1b6044820152606401610223565b8373__$c7dbd794b8c7b5c2028db781007df1176e$__6379de4601602084013560051b600587866060013560405160200161061a91815260200190565b60408051601f198184030181529190528051602090910120610640610100890189610b27565b6040518763ffffffff1660e01b815260040161066196959493929190610b78565b602060405180830381865af415801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a29190610bcf565b146106ef5760405162461bcd60e51b815260206004820152601e60248201527f6f75747075747345706f6368526f6f744861736820696e636f727265637400006044820152606401610223565b600073__$c7dbd794b8c7b5c2028db781007df1176e$__63c84583a1888051906020012060405160200161072591815260200190565b60405160208183030381529060405260056040518363ffffffff1660e01b8152600401610753929190610be8565b602060405180830381865af4158015610770573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107949190610bcf565b9050606082013573__$c7dbd794b8c7b5c2028db781007df1176e$__6379de4601604085013560051b600587866107ce60e08a018a610b27565b6040518763ffffffff1660e01b81526004016107ef96959493929190610b78565b602060405180830381865af415801561080c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108309190610bcf565b1461087d5760405162461bcd60e51b815260206004820152601e60248201527f6f7574707574486173686573526f6f744861736820696e636f727265637400006044820152606401610223565b50505050505050565b6000806040838503121561089957600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600061012082840312156108d157600080fd5b50919050565b6000806000606084860312156108ec57600080fd5b833567ffffffffffffffff8082111561090457600080fd5b818601915086601f83011261091857600080fd5b81358181111561092a5761092a6108a8565b604051601f8201601f19908116603f01168101908382118183101715610952576109526108a8565b8160405282815289602084870101111561096b57600080fd5b8260208601602083013760006020848301015280975050505060208601359350604086013591508082111561099f57600080fd5b506109ac868287016108be565b9150509250925092565b6000806000606084860312156109cb57600080fd5b505081359360208301359350604090920135919050565b600080600080606085870312156109f857600080fd5b84356001600160a01b0381168114610a0f57600080fd5b9350602085013567ffffffffffffffff80821115610a2c57600080fd5b818701915087601f830112610a4057600080fd5b813581811115610a4f57600080fd5b886020828501011115610a6157600080fd5b602083019550809450506040870135915080821115610a7f57600080fd5b50610a8c878288016108be565b91505092959194509250565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610b0057600080fd5b81518015158114610b1057600080fd5b9392505050565b8183823760009101908152919050565b6000808335601e19843603018112610b3e57600080fd5b83018035915067ffffffffffffffff821115610b5957600080fd5b6020019150600581901b3603821315610b7157600080fd5b9250929050565b86815285602082015284604082015283606082015260a060808201528160a0820152600060018060fb1b03831115610baf57600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b600060208284031215610be157600080fd5b5051919050565b604081526000835180604084015260005b81811015610c165760208187018101516060868401015201610bf9565b81811115610c28576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fea2646970667358221220466e987a6ad69c9b9648327f0c965f4c05297bb68be7c1491af5e8f2fc075ca064736f6c634300080d0033", + "libraries": { + "Bitmask": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "Merkle": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" + }, + "devdoc": { + "kind": "dev", + "methods": { + "executeVoucher(address,bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))": { + "details": "vouchers can only be executed once", + "params": { + "_destination": "address that will execute the payload", + "_payload": "payload to be executed by destination", + "_v": "validity proof for this encoded voucher" + }, + "returns": { + "_0": "true if voucher was executed successfully" + } + }, + "getBitMaskPosition(uint256,uint256,uint256)": { + "params": { + "_epoch": "which epoch the voucher belongs to", + "_input": "which input, inside the epoch, the voucher belongs to", + "_voucher": "of voucher inside the input" + }, + "returns": { + "_0": "position of that voucher on bitmask" + } + }, + "getIntraDrivePosition(uint256,uint256)": { + "params": { + "_index": "index of intra memory range", + "_log2Size": "of intra memory range" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "executeVoucher(address,bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))": { + "notice": "executes voucher" + }, + "getBitMaskPosition(uint256,uint256,uint256)": { + "notice": "get voucher position on bitmask" + }, + "getEpochNoticeLog2Size()": { + "notice": "get log2 size of epoch notice memory range" + }, + "getEpochVoucherLog2Size()": { + "notice": "get log2 size of epoch voucher memory range" + }, + "getNoticeMetadataLog2Size()": { + "notice": "get log2 size of notice metadata memory range" + }, + "getNumberOfFinalizedEpochs()": { + "notice": "get number of finalized epochs" + }, + "getVoucherMetadataLog2Size()": { + "notice": "get log2 size of voucher metadata memory range" + }, + "isValidNoticeProof(bytes,bytes32,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))": { + "notice": "isValidNoticeProof reverts if the proof is invalid" + }, + "isValidVoucherProof(bytes,bytes32,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))": { + "notice": "isValidVoucherProof reverts if the proof is invalid" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/OwnershipFacet.json b/echo-js/deployments/localhost/OwnershipFacet.json new file mode 100644 index 00000000..1faf973c --- /dev/null +++ b/echo-js/deployments/localhost/OwnershipFacet.json @@ -0,0 +1,105 @@ +{ + "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x80e062474a7a1e9dbb655053703b048ef42744b554cdc57530cc04e49ef2e66f", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "transactionIndex": 0, + "gasUsed": "179473", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd1729958723714bfd7efc05c1d51d1f971aa290b6483b5acc668064d45991a4d", + "transactionHash": "0x80e062474a7a1e9dbb655053703b048ef42744b554cdc57530cc04e49ef2e66f", + "logs": [], + "blockNumber": 14, + "cumulativeGasUsed": "179473", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {IERC173} from \\\"../interfaces/IERC173.sol\\\";\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0x08a198b9541f25536ae7fa16f3de069de7450f66709605911e34834e65ad6419\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\\n}\\n\",\"keccak256\":\"0x6a3129be1f39b6fec871f2c94bf7debf2d6a4e665547a4d83e7f2def38359e44\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0xc47289cda9c9cdb749612eb82ccb9abf9ab08dca74bdca22292ae7f765a15a5f\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(\\n msg.sender == diamondStorage().contractOwner,\\n \\\"LibDiamond: Must be contract owner\\\"\\n );\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] diamondCut,\\n address init,\\n bytes callData\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (\\n uint256 selectorIndex;\\n selectorIndex < _selectors.length;\\n selectorIndex++\\n ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata)\\n internal\\n {\\n if (_init == address(0)) {\\n require(\\n _calldata.length == 0,\\n \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\"\\n );\\n } else {\\n require(\\n _calldata.length > 0,\\n \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\"\\n );\\n if (_init != address(this)) {\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n }\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x740ea3845282f09bb822e66a189ed431ac799ab08184de7457ef53799b2e99d6\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610248806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461005f575b600080fd5b610043610074565b6040516001600160a01b03909116815260200160405180910390f35b61007261006d3660046101e2565b6100ac565b005b60006100a77fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031690565b905090565b6100b46100c0565b6100bd8161014d565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b0316331461014b5760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6000602082840312156101f457600080fd5b81356001600160a01b038116811461020b57600080fd5b939250505056fea264697066735822122028a4df310106ca3538d88cb1b0ac2c4586b78c8eafbbc533269b52abf6654d8d64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461005f575b600080fd5b610043610074565b6040516001600160a01b03909116815260200160405180910390f35b61007261006d3660046101e2565b6100ac565b005b60006100a77fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031690565b905090565b6100b46100c0565b6100bd8161014d565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b0316331461014b5760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6000602082840312156101f457600080fd5b81356001600160a01b038116811461020b57600080fd5b939250505056fea264697066735822122028a4df310106ca3538d88cb1b0ac2c4586b78c8eafbbc533269b52abf6654d8d64736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "returns": { + "owner_": "The address of the owner." + } + }, + "transferOwnership(address)": { + "details": "Set _newOwner to address(0) to renounce any ownership.", + "params": { + "_newOwner": "The address of the new owner of the contract" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "owner()": { + "notice": "Get the address of the owner" + }, + "transferOwnership(address)": { + "notice": "Set the address of the new owner of the contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/RollupsFacet.json b/echo-js/deployments/localhost/RollupsFacet.json new file mode 100644 index 00000000..1e031563 --- /dev/null +++ b/echo-js/deployments/localhost/RollupsFacet.json @@ -0,0 +1,295 @@ +{ + "address": "0x09635F643e140090A9A8Dcd712eD6285858ceBef", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "claimer", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "epochHash", + "type": "bytes32" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "epochHash", + "type": "bytes32" + } + ], + "name": "FinalizeEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Phase", + "name": "newPhase", + "type": "uint8" + } + ], + "name": "PhaseChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "loser", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "winningClaim", + "type": "bytes32" + } + ], + "name": "ResolveDispute", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_epochHash", + "type": "bytes32" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "finalizeEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getChallengePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentPhase", + "outputs": [ + { + "internalType": "enum Phase", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputAccumulationStart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInputDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSealingEpochTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTemplateHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xe9686301791672797d70426db27ef8ff18afc98cb7c85cd4ff8143cb73e384ea", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x09635F643e140090A9A8Dcd712eD6285858ceBef", + "transactionIndex": 0, + "gasUsed": "1327531", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd8a3728954c2373bd2b83519c81bb0aba9b9003ce7c78f66a61c36eff153ca4e", + "transactionHash": "0xe9686301791672797d70426db27ef8ff18afc98cb7c85cd4ff8143cb73e384ea", + "logs": [], + "blockNumber": 28, + "cumulativeGasUsed": "1327531", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epochNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"epochHash\",\"type\":\"bytes32\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"epochNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"epochHash\",\"type\":\"bytes32\"}],\"name\":\"FinalizeEpoch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Phase\",\"name\":\"newPhase\",\"type\":\"uint8\"}],\"name\":\"PhaseChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"loser\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"winningClaim\",\"type\":\"bytes32\"}],\"name\":\"ResolveDispute\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_epochHash\",\"type\":\"bytes32\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalizeEpoch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChallengePeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentPhase\",\"outputs\":[{\"internalType\":\"enum Phase\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputAccumulationStart\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSealingEpochTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTemplateHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"claim(bytes32)\":{\"details\":\"ValidatorManager makes sure that msg.sender is allowed and that claim != bytes32(0) TODO: add signatures for aggregated claims\",\"params\":{\"_epochHash\":\"hash of epoch\"}},\"finalizeEpoch()\":{\"details\":\"can only be called if challenge period is over\"},\"getCurrentEpoch()\":{\"details\":\"if phase is input accumulation, then the epoch number is length of finalized epochs array, else there are two non finalized epochs, one awaiting consensus/dispute and another accumulating input\",\"returns\":{\"_0\":\"index of current epoch\"}}},\"version\":1},\"userdoc\":{\"events\":{\"Claim(uint256,address,bytes32)\":{\"notice\":\"claim submitted\"},\"FinalizeEpoch(uint256,bytes32)\":{\"notice\":\"epoch finalized\"},\"PhaseChange(uint8)\":{\"notice\":\"phase change\"},\"ResolveDispute(address,address,bytes32)\":{\"notice\":\"dispute resolved\"}},\"kind\":\"user\",\"methods\":{\"claim(bytes32)\":{\"notice\":\"claim the result of current epoch\"},\"finalizeEpoch()\":{\"notice\":\"finalize epoch after timeout\"},\"getChallengePeriod()\":{\"notice\":\"returns the challenge period in seconds\"},\"getCurrentEpoch()\":{\"notice\":\"returns index of current (accumulating) epoch\"},\"getCurrentPhase()\":{\"notice\":\"returns the current phase\"},\"getInputAccumulationStart()\":{\"notice\":\"returns the input accumulation start timestamp\"},\"getInputDuration()\":{\"notice\":\"returns the input duration in seconds\"},\"getSealingEpochTimestamp()\":{\"notice\":\"returns the sealing epoch timestamp\"},\"getTemplateHash()\":{\"notice\":\"returns the machine's template hash\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/RollupsFacet.sol\":\"RollupsFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/RollupsFacet.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups facet\\npragma solidity ^0.8.0;\\n\\nimport {IRollups, Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\n\\ncontract RollupsFacet is IRollups {\\n ////\\n // All claims agreed OR challenge period ended\\n // functions: claim() or finalizeEpoch()\\n // +--------------------------------------------------+\\n // | |\\n // +--------v-----------+ new input after IPAD +---------+----------+\\n // | +--------------------------->+ |\\n // START ---> | Input Accumulation | firt claim after IPAD | Awaiting Consensus |\\n // | +--------------------------->+ |\\n // +-+------------------+ +-----------------+--+\\n // ^ ^ |\\n // | dispute resolved | |\\n // | dispute resolved before challenge | |\\n // | after challenge +--------------------+ period ended | |\\n // | period ended | +---------------------+ |\\n // +----------------------+ Awaiting Dispute | |\\n // | +<-----------------------+\\n // +--------------------+ conflicting claim\\n ///\\n\\n using LibRollups for LibRollups.DiamondStorage;\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) public override {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n\\n Phase currentPhase = Phase(rollupsDS.currentPhase_int);\\n uint256 inputAccumulationStart = rollupsDS.inputAccumulationStart;\\n uint256 inputDuration = rollupsDS.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n currentPhase = Phase.AwaitingConsensus;\\n rollupsDS.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n\\n // warns input of new epoch\\n inputDS.onNewInputAccumulation();\\n // update timestamp of sealing epoch proposal\\n rollupsDS.sealingEpochTimestamp = uint32(block.timestamp);\\n }\\n\\n require(\\n currentPhase == Phase.AwaitingConsensus,\\n \\\"Phase != AwaitingConsensus\\\"\\n );\\n (result, claims, claimers) = validatorManagerDS.onClaim(\\n payable(msg.sender),\\n _epochHash\\n );\\n\\n // emit the claim event before processing it\\n // so if the epoch is finalized in this claim (consensus)\\n // the number of final epochs doesnt gets contaminated\\n emit Claim(\\n outputDS.getNumberOfFinalizedEpochs(),\\n msg.sender,\\n _epochHash\\n );\\n\\n rollupsDS.resolveValidatorResult(result, claims, claimers);\\n }\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() public override {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n Phase currentPhase = Phase(rollupsDS.currentPhase_int);\\n require(\\n currentPhase == Phase.AwaitingConsensus,\\n \\\"Phase != Awaiting Consensus\\\"\\n );\\n\\n uint256 sealingEpochTimestamp = rollupsDS.sealingEpochTimestamp;\\n uint256 challengePeriod = rollupsDS.challengePeriod;\\n require(\\n block.timestamp > sealingEpochTimestamp + challengePeriod,\\n \\\"Challenge period not over\\\"\\n );\\n\\n require(\\n validatorManagerDS.currentClaim != bytes32(0),\\n \\\"No Claim to be finalized\\\"\\n );\\n\\n rollupsDS.startNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch() public view override returns (uint256) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return rollupsDS.getCurrentEpoch();\\n }\\n\\n /// @notice returns the current phase\\n function getCurrentPhase() public view returns (Phase) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return Phase(rollupsDS.currentPhase_int);\\n }\\n\\n /// @notice returns the input accumulation start timestamp\\n function getInputAccumulationStart() public view returns (uint256) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return uint256(rollupsDS.inputAccumulationStart);\\n }\\n\\n /// @notice returns the sealing epoch timestamp\\n function getSealingEpochTimestamp() public view returns (uint256) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return uint256(rollupsDS.sealingEpochTimestamp);\\n }\\n\\n /// @notice returns the input duration in seconds\\n function getInputDuration() public view returns (uint256) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return uint256(rollupsDS.inputDuration);\\n }\\n\\n /// @notice returns the challenge period in seconds\\n function getChallengePeriod() public view returns (uint256) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return uint256(rollupsDS.challengePeriod);\\n }\\n\\n /// @notice returns the machine's template hash\\n function getTemplateHash() public view returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n return rollupsDS.templateHash;\\n }\\n}\\n\",\"keccak256\":\"0xb4fa1894b1be726ec583569a1027ce9d509528fcb5e1e012228344b5a7343360\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups interface\\npragma solidity >=0.7.0;\\n\\n// InputAccumulation - Inputs being accumulated for currrent epoch\\n// AwaitingConsensus - No disagreeing claims (or no claims)\\n// AwaitingDispute - Waiting for dispute to be over\\n// inputs received during InputAccumulation will be included in the\\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\\n// are accumulated for the next epoch\\nenum Phase {\\n InputAccumulation,\\n AwaitingConsensus,\\n AwaitingDispute\\n}\\n\\ninterface IRollups {\\n /// @notice claim the result of current epoch\\n /// @param _epochHash hash of epoch\\n /// @dev ValidatorManager makes sure that msg.sender is allowed\\n /// and that claim != bytes32(0)\\n /// TODO: add signatures for aggregated claims\\n function claim(bytes32 _epochHash) external;\\n\\n /// @notice finalize epoch after timeout\\n /// @dev can only be called if challenge period is over\\n function finalizeEpoch() external;\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two epochs two non\\n /// finalized epochs, one awaiting consensus/dispute and another\\n /// accumulating input\\n function getCurrentEpoch() external view returns (uint256);\\n\\n /// @notice claim submitted\\n /// @param epochHash claim being submitted by this epoch\\n /// @param claimer address of current claimer\\n /// @param epochNumber number of the epoch being submitted\\n event Claim(\\n uint256 indexed epochNumber,\\n address claimer,\\n bytes32 epochHash\\n );\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n}\\n\",\"keccak256\":\"0x241c3ee8bb900067903ac836d5f3ee81eca587c7f225ad6df686478a6b27329b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDisputeManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Dispute Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibDisputeManager {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n /// @notice initiates a dispute betweent two players\\n /// @param claims conflicting claims\\n /// @param claimers addresses of senders of conflicting claim\\n /// @dev this is a mock implementation that just gives the win\\n /// to the address in the first posititon of claimers array\\n function initiateDispute(\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\\n }\\n}\\n\",\"keccak256\":\"0x7d3fdb94a17c7f61ef8f6431f42eaa307b30398e3c24093c0526f449752563c9\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibInput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Input library\\npragma solidity ^0.8.0;\\n\\nimport {LibRollups} from \\\"../libraries/LibRollups.sol\\\";\\n\\nlibrary LibInput {\\n using LibRollups for LibRollups.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Input.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n // always needs to keep track of two input boxes:\\n // 1 for the input accumulation of next epoch\\n // and 1 for the messages during current epoch. To save gas we alternate\\n // between inputBox0 and inputBox1\\n bytes32[] inputBox0;\\n bytes32[] inputBox1;\\n uint256 inputDriveSize; // size of input flashdrive\\n uint256 currentInputBox;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice get input inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @param index index of input inside that inbox\\n /// @return hash of input at index index\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getInput(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (bytes32)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\\n }\\n\\n /// @notice get number of inputs inside inbox of currently proposed claim\\n /// @param ds diamond storage pointer\\n /// @return number of inputs on that input box\\n /// @dev currentInputBox being zero means that the inputs for\\n /// the claimed epoch are on input box one\\n function getNumberOfInputs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return\\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\\n }\\n\\n /// @notice add input to processed by next epoch\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, msg.sender);\\n }\\n\\n /// @notice add internal input to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\\n internal\\n returns (bytes32)\\n {\\n return addInputFromSender(ds, input, address(this));\\n }\\n\\n /// @notice add input from a specific sender to processed by next epoch\\n /// @notice this function is to be reserved for internal usage only\\n /// @notice for normal inputs, call `addInput` instead\\n /// @param ds diamond storage pointer\\n /// @param input input to be understood by offchain machine\\n /// @param sender input sender address\\n /// @dev offchain code is responsible for making sure\\n /// that input size is power of 2 and multiple of 8 since\\n /// the offchain machine has a 8 byte word\\n function addInputFromSender(\\n DiamondStorage storage ds,\\n bytes memory input,\\n address sender\\n ) internal returns (bytes32) {\\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\\n .diamondStorage();\\n\\n require(input.length <= ds.inputDriveSize, \\\"input len: [0,driveSize]\\\");\\n\\n // notifyInput returns true if that input\\n // belongs to a new epoch\\n if (rollupsDS.notifyInput()) {\\n swapInputBox(ds);\\n }\\n\\n // points to correct inputBox\\n bytes32[] storage inputBox = ds.currentInputBox == 0\\n ? ds.inputBox0\\n : ds.inputBox1;\\n\\n // get current epoch index\\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\\n\\n // keccak 64 bytes into 32 bytes\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n block.number,\\n block.timestamp,\\n currentEpoch, // epoch index\\n inputBox.length // input index\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n emit InputAdded(\\n currentEpoch,\\n inputBox.length - 1,\\n sender,\\n block.timestamp,\\n input\\n );\\n\\n return inputHash;\\n }\\n\\n /// @notice called when a new input accumulation phase begins\\n /// swap inbox to receive inputs for upcoming epoch\\n /// @param ds diamond storage pointer\\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\\n swapInputBox(ds);\\n }\\n\\n /// @notice called when a new epoch begins, clears deprecated inputs\\n /// @param ds diamond storage pointer\\n function onNewEpoch(DiamondStorage storage ds) internal {\\n // clear input box for new inputs\\n // the current input box should be accumulating inputs\\n // for the new epoch already. So we clear the other one.\\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\\n }\\n\\n /// @notice changes current input box\\n /// @param ds diamond storage pointer\\n function swapInputBox(DiamondStorage storage ds) internal {\\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\\n }\\n\\n /// @notice input added\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender\\n /// @param timestamp block.timestamp\\n /// @param input input data\\n event InputAdded(\\n uint256 indexed epochNumber,\\n uint256 indexed inputIndex,\\n address sender,\\n uint256 timestamp,\\n bytes input\\n );\\n}\\n\",\"keccak256\":\"0x9fec6d72c872e8f7f3adc79fa2bc5de8396d6ae97e2e23817e780e7d7a6cfaea\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibOutput.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Output library\\npragma solidity ^0.8.0;\\n\\nlibrary LibOutput {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Output.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n mapping(uint256 => uint256) voucherBitmask;\\n bytes32[] epochHashes;\\n bool lock; //reentrancy lock\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice to be called when an epoch is finalized\\n /// @param ds diamond storage pointer\\n /// @param epochHash hash of finalized epoch\\n /// @dev an epoch being finalized means that its vouchers can be called\\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\\n ds.epochHashes.push(epochHash);\\n }\\n\\n /// @notice get number of finalized epochs\\n /// @param ds diamond storage pointer\\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xd0f88e13210013e9d5bde03399bb76304d6ab4e1f06d01c7e3525adc87a2d65e\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibRollups.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Rollups library\\npragma solidity ^0.8.0;\\n\\nimport {Phase} from \\\"../interfaces/IRollups.sol\\\";\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibInput} from \\\"../libraries/LibInput.sol\\\";\\nimport {LibOutput} from \\\"../libraries/LibOutput.sol\\\";\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibDisputeManager} from \\\"../libraries/LibDisputeManager.sol\\\";\\n\\nlibrary LibRollups {\\n using LibInput for LibInput.DiamondStorage;\\n using LibOutput for LibOutput.DiamondStorage;\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"Rollups.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 templateHash; // state hash of the cartesi machine at t0\\n uint32 inputDuration; // duration of input accumulation phase in seconds\\n uint32 challengePeriod; // duration of challenge period in seconds\\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\\n uint32 currentPhase_int; // current phase in integer form\\n }\\n\\n /// @notice epoch finalized\\n /// @param epochNumber number of the epoch being finalized\\n /// @param epochHash claim being submitted by this epoch\\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\\n\\n /// @notice dispute resolved\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\\n\\n /// @notice phase change\\n /// @param newPhase new phase\\n event PhaseChange(Phase newPhase);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when new input arrives, manages the phase changes\\n /// @param ds diamond storage pointer\\n /// @dev can only be called by input contract\\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\\n uint256 inputDuration = ds.inputDuration;\\n\\n if (\\n currentPhase == Phase.InputAccumulation &&\\n block.timestamp > inputAccumulationStart + inputDuration\\n ) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n return true;\\n }\\n return false;\\n }\\n\\n /// @notice called when a dispute is resolved by the dispute manager\\n /// @param ds diamond storage pointer\\n /// @param winner winner of dispute\\n /// @param loser loser of dispute\\n /// @param winningClaim initial claim of winning validator\\n function resolveDispute(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n ) internal {\\n Result result;\\n bytes32[2] memory claims;\\n address payable[2] memory claimers;\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\\n winner,\\n loser,\\n winningClaim\\n );\\n\\n // restart challenge period\\n ds.sealingEpochTimestamp = uint32(block.timestamp);\\n\\n emit ResolveDispute(winner, loser, winningClaim);\\n resolveValidatorResult(ds, result, claims, claimers);\\n }\\n\\n /// @notice resolve results returned by validator manager\\n /// @param ds diamond storage pointer\\n /// @param result result from claim or dispute operation\\n /// @param claims array of claims in case of new conflict\\n /// @param claimers array of claimers in case of new conflict\\n function resolveValidatorResult(\\n DiamondStorage storage ds,\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory claimers\\n ) internal {\\n if (result == Result.NoConflict) {\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingConsensus) {\\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\\n emit PhaseChange(Phase.AwaitingConsensus);\\n }\\n } else if (result == Result.Consensus) {\\n startNewEpoch(ds);\\n } else {\\n // for the case when result == Result.Conflict\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n if (currentPhase != Phase.AwaitingDispute) {\\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\\n emit PhaseChange(Phase.AwaitingDispute);\\n }\\n LibDisputeManager.initiateDispute(claims, claimers);\\n }\\n }\\n\\n /// @notice starts new epoch\\n /// @param ds diamond storage pointer\\n function startNewEpoch(DiamondStorage storage ds) internal {\\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n\\n // reset input accumulation start and deactivate challenge period start\\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\\n emit PhaseChange(Phase.InputAccumulation);\\n ds.inputAccumulationStart = uint32(block.timestamp);\\n ds.sealingEpochTimestamp = type(uint32).max;\\n\\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\\n\\n // emit event before finalized epoch is added to the Output storage\\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\\n\\n outputDS.onNewEpoch(finalClaim);\\n inputDS.onNewEpoch();\\n }\\n\\n /// @notice returns index of current (accumulating) epoch\\n /// @param ds diamond storage pointer\\n /// @return index of current epoch\\n /// @dev if phase is input accumulation, then the epoch number is length\\n /// of finalized epochs array, else there are two non finalized epochs,\\n /// one awaiting consensus/dispute and another accumulating input\\n function getCurrentEpoch(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\\n\\n Phase currentPhase = Phase(ds.currentPhase_int);\\n\\n return\\n currentPhase == Phase.InputAccumulation\\n ? finalizedEpochs\\n : finalizedEpochs + 1;\\n }\\n}\\n\",\"keccak256\":\"0x04f72881c6032af40537ac14ff3720df2899a5746a42abd841b2292d66db11ca\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061170f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063a3a40ea511610066578063a3a40ea51461010b578063b97dd9e214610120578063bd66528a14610128578063ddf7bcf01461013b578063e17ba0121461015d57600080fd5b806354ee1da51461009857806361b12c66146100c95780637864b77d146100de57806382ae9ef714610101575b600080fd5b60008051602061165a83398151915254600160601b900463ffffffff165b6040519081526020015b60405180910390f35b6000805160206116ba833981519152546100b6565b60008051602061165a83398151915254640100000000900463ffffffff166100b6565b610109610178565b005b610113610304565b6040516100c091906114fb565b6100b661034b565b61010961013636600461150e565b610365565b60008051602061165a83398151915254600160401b900463ffffffff166100b6565b60008051602061165a8339815191525463ffffffff166100b6565b60008051602061165a833981519152546000805160206116ba8339815191529060008051602061169a83398151915290600090600160801b900463ffffffff1660028111156101c9576101c96114c7565b905060018160028111156101df576101df6114c7565b146102315760405162461bcd60e51b815260206004820152601b60248201527f506861736520213d204177616974696e6720436f6e73656e737573000000000060448201526064015b60405180910390fd5b600183015463ffffffff600160601b8204811691640100000000900416610258818361153d565b42116102a65760405162461bcd60e51b815260206004820152601960248201527f4368616c6c656e676520706572696f64206e6f74206f766572000000000000006044820152606401610228565b83546102f45760405162461bcd60e51b815260206004820152601860248201527f4e6f20436c61696d20746f2062652066696e616c697a656400000000000000006044820152606401610228565b6102fd8561057f565b5050505050565b60008051602061165a833981519152546000906000805160206116ba83398151915290600160801b900463ffffffff166002811115610345576103456114c7565b91505090565b60006000805160206116ba833981519152610345816106b7565b6000805160206116ba8339815191527f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56660008051602061169a83398151915260006103cf611477565b6103d7611477565b6001870154600090600160801b900463ffffffff1660028111156103fd576103fd6114c7565b600189015490915063ffffffff600160401b8204811691166000836002811115610429576104296114c7565b14801561043e575061043b818361153d565b42115b156104af5760018a8101805463ffffffff60801b1916600160801b17905560405190935060008051602061167a8339815191529061047d9085906114fb565b60405180910390a161048e89610759565b60018a01805463ffffffff60601b1916600160601b4263ffffffff16021790555b60018360028111156104c3576104c36114c7565b146105105760405162461bcd60e51b815260206004820152601a60248201527f506861736520213d204177616974696e67436f6e73656e7375730000000000006044820152606401610228565b61051b87338d610765565b9197509550935061052d886001015490565b60408051338152602081018e90527fd31325e5dc55b03edf08c70299d3b1bc8d4c2ca8512c90138ddd03e3f54fce6c910160405180910390a26105728a878787610986565b5050505050505050505050565b60018101805463ffffffff60801b191690556040517f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060008051602061169a8339815191529060008051602061167a83398151915290610604906000906114fb565b60405180910390a160018401805463ffffffff60601b1963ffffffff4216600160401b02166fffffffffffffffff0000000000000000199091161763ffffffff60601b179055600061065582610adc565b9050610662836001015490565b6040518281527f6e3d05bc77b9307d9ba574c7c3196a746edd51104ded1c823edc63be4b8a63c39060200160405180910390a2600180840180549182018155600090815260209020018190556102fd84610b39565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff166002811115610723576107236114c7565b90506000816002811115610739576107396114c7565b1461074e5761074982600161153d565b610750565b815b95945050505050565b61076281610b5c565b50565b600061076f611477565b610777611477565b836107b25760405162461bcd60e51b815260206004820152600b60248201526a656d70747920636c61696d60a81b6044820152606401610228565b6107bc8686610b7b565b6107fd5760405162461bcd60e51b81526020600482015260126024820152711cd95b99195c881b9bdd08185b1b1bddd95960721b6044820152606401610228565b60006108098787610c2a565b600388015490915060f81c811c600116156108765760405162461bcd60e51b815260206004820152602760248201527f73656e6465722068616420636c61696d656420696e20746869732065706f6368604482015266206265666f726560c81b6064820152608401610228565b8654610884578487556108e4565b865485146108e4576108d8600260405180604001604052808a6000015481526020018881525060405180604001604052806108be8c610d09565b6001600160a01b0390811682528b16602090910152610dc3565b9350935093505061097d565b6108ee8787610e1c565b6108f787610e47565b61093b576040805180820182528681526000602080830182905283518085019094526001600160a01b038a168452830181905261093692909190610dc3565b610975565b6040805180820182528681526000602080830182905283518085019094526001600160a01b038a1684528301526109759160019190610dc3565b935093509350505b93509350939050565b600083600281111561099a5761099a6114c7565b03610a24576001840154600090600160801b900463ffffffff1660028111156109c5576109c56114c7565b905060018160028111156109db576109db6114c7565b14610a1e576001858101805463ffffffff60801b1916600160801b17905560405160008051602061167a83398151915291610a15916114fb565b60405180910390a15b50610ad6565b6001836002811115610a3857610a386114c7565b03610a4b57610a468461057f565b610ad6565b6001840154600090600160801b900463ffffffff166002811115610a7157610a716114c7565b90506002816002811115610a8757610a876114c7565b14610acc5760018501805463ffffffff60801b1916600160811b17905560405160008051602061167a83398151915290610ac3906002906114fb565b60405180910390a15b6102fd8383610e69565b50505050565b6000610ae782610e92565b81546000835560038301546001600160f81b031660038401556040518181527fddc860800a99149017c480ec51523bf4143b7215e78956ae5c31e5c568f5383a9060200160405180910390a192915050565b600381015415610b4e57610762816000611495565b610762600182016000611495565b600381015415610b6d576000610b70565b60015b60ff16600390910155565b60006001600160a01b038216610bbf5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610c1e57836001018181548110610be357610be3611555565b6000918252602090912001546001600160a01b0390811690841603610c0c576001915050610c24565b80610c168161156b565b915050610bc2565b50600090505b92915050565b60006001600160a01b038216610c6e5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610cca57836001018181548110610c9257610c92611555565b6000918252602090912001546001600160a01b0390811690841603610cb8579050610c24565b80610cc28161156b565b915050610c71565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b6044820152606401610228565b600080610d1a836003015460f81c90565b905060005b6001840154811015610d7a576001811b821615610d6857836001018181548110610d4b57610d4b611555565b6000918252602090912001546001600160a01b0316949350505050565b80610d728161156b565b915050610d1f565b5060405162461bcd60e51b815260206004820152601c60248201527f4167726565696e672076616c696461746f72206e6f7420666f756e64000000006044820152606401610228565b6000610dcd611477565b610dd5611477565b7f495383aed97965c56495cdbadedfe9667a1b028c54d3fc4b5335895146e02b70868686604051610e0893929190611584565b60405180910390a150939492935090919050565b6000610e288383610c2a565b6003840154909150610e3a9082610ee7565b8360030181905550505050565b600381015460009060f081901c60ff16610e618260f81c90565b149392505050565b8051602082015183516000805160206116ba83398151915292610e8d928492610f25565b505050565b6000610ea2826003015460f81c90565b905060005b6001830154811015610e8d576001811b821615610ed5576003830154610ecf90826001610fdb565b60038401555b80610edf8161156b565b915050610ea7565b600060088210610f095760405162461bcd60e51b8152600401610228906115f7565b6000610f168360f861153d565b6001901b841791505092915050565b6000610f2f611477565b610f37611477565b60008051602061169a833981519152610f528188888861102e565b60018b01805463ffffffff60601b1916600160601b4263ffffffff1602179055604080516001600160a01b03808d1682528b16602082015290810189905292965090945092507f2afbde4d47160a9c5de25b0df88d5b83e705286f2a447cac162db5e99ad6f5d29060600160405180910390a1610fd188858585610986565b5050505050505050565b600060088310610ffd5760405162461bcd60e51b8152600401610228906115f7565b600061100985856111e2565b90506000611017848361153d565b9050611024868683611230565b9695505050505050565b6000611038611477565b611040611477565b61104a87866112e4565b865484036110e45761105b87610e47565b61109f576040805180820182528581526000602080830182905283518085019094526001600160a01b038a168452830181905261109a929091906113b8565b6110d9565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526110d991600191906113b8565b9250925092506111d8565b600387015460f81c1561113d576110d9600260405180604001604052808a6000015481526020018781525060405180604001604052806111238c610d09565b6001600160a01b0390811682528b166020909101526113b8565b83875561114a8787610e1c565b61115387610e47565b611197576040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301819052611192929091906113b8565b6111d1565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526111d191600191906113b8565b9250925092505b9450945094915050565b6000600882106112045760405162461bcd60e51b8152600401610228906115f7565b600061121560016340000000611623565b90508061122384601e61163a565b85901c1691505092915050565b6000600883106112525760405162461bcd60e51b8152600401610228906115f7565b61126160016340000000611623565b8211156112a65760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b6044820152606401610228565b60006112b384601e61163a565b6112c260016340000000611623565b901b1990508481166112d585601e61163a565b9390931b909217949350505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7360005b6001840154811015610ad65783600101818154811061132957611329611555565b6000918252602090912001546001600160a01b03908116908416036113a657600084600101828154811061135f5761135f611555565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600384015461139790826113fd565b6003850155610a46828261145a565b806113b08161156b565b915050611308565b60006113c2611477565b6113ca611477565b7f09201c193a07cae1df95ae692cc698685574c942a04514c48a4c3249f38594ff868686604051610e0893929190611584565b60006008821061141f5760405162461bcd60e51b8152600401610228906115f7565b82600061142d8460f861153d565b6001901b199182169190506114438460f061153d565b6001901b1991821691905061075082856000611230565b600382015461146b90826000611230565b82600301819055505050565b60405180604001604052806002906020820280368337509192915050565b508054600082559060005260206000209081019061076291905b808211156114c357600081556001016114af565b5090565b634e487b7160e01b600052602160045260246000fd5b6003811061076257634e487b7160e01b600052602160045260246000fd5b60208101611508836114dd565b91905290565b60006020828403121561152057600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561155057611550611527565b500190565b634e487b7160e01b600052603260045260246000fd5b60006001820161157d5761157d611527565b5060010190565b60a08101611591856114dd565b84825260208083018560005b60028110156115ba5781518352918301919083019060010161159d565b505050606083018460005b60028110156115eb5781516001600160a01b0316835291830191908301906001016115c5565b50505050949350505050565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b60008282101561163557611635611527565b500390565b600081600019048311821515161561165457611654611527565b50029056fed32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ded606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fcd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ca264697066735822122005a48434be4f5e94111d6d06fc627e4729c541be34424a5e0fb455dd1e4422ab64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063a3a40ea511610066578063a3a40ea51461010b578063b97dd9e214610120578063bd66528a14610128578063ddf7bcf01461013b578063e17ba0121461015d57600080fd5b806354ee1da51461009857806361b12c66146100c95780637864b77d146100de57806382ae9ef714610101575b600080fd5b60008051602061165a83398151915254600160601b900463ffffffff165b6040519081526020015b60405180910390f35b6000805160206116ba833981519152546100b6565b60008051602061165a83398151915254640100000000900463ffffffff166100b6565b610109610178565b005b610113610304565b6040516100c091906114fb565b6100b661034b565b61010961013636600461150e565b610365565b60008051602061165a83398151915254600160401b900463ffffffff166100b6565b60008051602061165a8339815191525463ffffffff166100b6565b60008051602061165a833981519152546000805160206116ba8339815191529060008051602061169a83398151915290600090600160801b900463ffffffff1660028111156101c9576101c96114c7565b905060018160028111156101df576101df6114c7565b146102315760405162461bcd60e51b815260206004820152601b60248201527f506861736520213d204177616974696e6720436f6e73656e737573000000000060448201526064015b60405180910390fd5b600183015463ffffffff600160601b8204811691640100000000900416610258818361153d565b42116102a65760405162461bcd60e51b815260206004820152601960248201527f4368616c6c656e676520706572696f64206e6f74206f766572000000000000006044820152606401610228565b83546102f45760405162461bcd60e51b815260206004820152601860248201527f4e6f20436c61696d20746f2062652066696e616c697a656400000000000000006044820152606401610228565b6102fd8561057f565b5050505050565b60008051602061165a833981519152546000906000805160206116ba83398151915290600160801b900463ffffffff166002811115610345576103456114c7565b91505090565b60006000805160206116ba833981519152610345816106b7565b6000805160206116ba8339815191527f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56660008051602061169a83398151915260006103cf611477565b6103d7611477565b6001870154600090600160801b900463ffffffff1660028111156103fd576103fd6114c7565b600189015490915063ffffffff600160401b8204811691166000836002811115610429576104296114c7565b14801561043e575061043b818361153d565b42115b156104af5760018a8101805463ffffffff60801b1916600160801b17905560405190935060008051602061167a8339815191529061047d9085906114fb565b60405180910390a161048e89610759565b60018a01805463ffffffff60601b1916600160601b4263ffffffff16021790555b60018360028111156104c3576104c36114c7565b146105105760405162461bcd60e51b815260206004820152601a60248201527f506861736520213d204177616974696e67436f6e73656e7375730000000000006044820152606401610228565b61051b87338d610765565b9197509550935061052d886001015490565b60408051338152602081018e90527fd31325e5dc55b03edf08c70299d3b1bc8d4c2ca8512c90138ddd03e3f54fce6c910160405180910390a26105728a878787610986565b5050505050505050505050565b60018101805463ffffffff60801b191690556040517f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060008051602061169a8339815191529060008051602061167a83398151915290610604906000906114fb565b60405180910390a160018401805463ffffffff60601b1963ffffffff4216600160401b02166fffffffffffffffff0000000000000000199091161763ffffffff60601b179055600061065582610adc565b9050610662836001015490565b6040518281527f6e3d05bc77b9307d9ba574c7c3196a746edd51104ded1c823edc63be4b8a63c39060200160405180910390a2600180840180549182018155600090815260209020018190556102fd84610b39565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff166002811115610723576107236114c7565b90506000816002811115610739576107396114c7565b1461074e5761074982600161153d565b610750565b815b95945050505050565b61076281610b5c565b50565b600061076f611477565b610777611477565b836107b25760405162461bcd60e51b815260206004820152600b60248201526a656d70747920636c61696d60a81b6044820152606401610228565b6107bc8686610b7b565b6107fd5760405162461bcd60e51b81526020600482015260126024820152711cd95b99195c881b9bdd08185b1b1bddd95960721b6044820152606401610228565b60006108098787610c2a565b600388015490915060f81c811c600116156108765760405162461bcd60e51b815260206004820152602760248201527f73656e6465722068616420636c61696d656420696e20746869732065706f6368604482015266206265666f726560c81b6064820152608401610228565b8654610884578487556108e4565b865485146108e4576108d8600260405180604001604052808a6000015481526020018881525060405180604001604052806108be8c610d09565b6001600160a01b0390811682528b16602090910152610dc3565b9350935093505061097d565b6108ee8787610e1c565b6108f787610e47565b61093b576040805180820182528681526000602080830182905283518085019094526001600160a01b038a168452830181905261093692909190610dc3565b610975565b6040805180820182528681526000602080830182905283518085019094526001600160a01b038a1684528301526109759160019190610dc3565b935093509350505b93509350939050565b600083600281111561099a5761099a6114c7565b03610a24576001840154600090600160801b900463ffffffff1660028111156109c5576109c56114c7565b905060018160028111156109db576109db6114c7565b14610a1e576001858101805463ffffffff60801b1916600160801b17905560405160008051602061167a83398151915291610a15916114fb565b60405180910390a15b50610ad6565b6001836002811115610a3857610a386114c7565b03610a4b57610a468461057f565b610ad6565b6001840154600090600160801b900463ffffffff166002811115610a7157610a716114c7565b90506002816002811115610a8757610a876114c7565b14610acc5760018501805463ffffffff60801b1916600160811b17905560405160008051602061167a83398151915290610ac3906002906114fb565b60405180910390a15b6102fd8383610e69565b50505050565b6000610ae782610e92565b81546000835560038301546001600160f81b031660038401556040518181527fddc860800a99149017c480ec51523bf4143b7215e78956ae5c31e5c568f5383a9060200160405180910390a192915050565b600381015415610b4e57610762816000611495565b610762600182016000611495565b600381015415610b6d576000610b70565b60015b60ff16600390910155565b60006001600160a01b038216610bbf5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610c1e57836001018181548110610be357610be3611555565b6000918252602090912001546001600160a01b0390811690841603610c0c576001915050610c24565b80610c168161156b565b915050610bc2565b50600090505b92915050565b60006001600160a01b038216610c6e5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610cca57836001018181548110610c9257610c92611555565b6000918252602090912001546001600160a01b0390811690841603610cb8579050610c24565b80610cc28161156b565b915050610c71565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b6044820152606401610228565b600080610d1a836003015460f81c90565b905060005b6001840154811015610d7a576001811b821615610d6857836001018181548110610d4b57610d4b611555565b6000918252602090912001546001600160a01b0316949350505050565b80610d728161156b565b915050610d1f565b5060405162461bcd60e51b815260206004820152601c60248201527f4167726565696e672076616c696461746f72206e6f7420666f756e64000000006044820152606401610228565b6000610dcd611477565b610dd5611477565b7f495383aed97965c56495cdbadedfe9667a1b028c54d3fc4b5335895146e02b70868686604051610e0893929190611584565b60405180910390a150939492935090919050565b6000610e288383610c2a565b6003840154909150610e3a9082610ee7565b8360030181905550505050565b600381015460009060f081901c60ff16610e618260f81c90565b149392505050565b8051602082015183516000805160206116ba83398151915292610e8d928492610f25565b505050565b6000610ea2826003015460f81c90565b905060005b6001830154811015610e8d576001811b821615610ed5576003830154610ecf90826001610fdb565b60038401555b80610edf8161156b565b915050610ea7565b600060088210610f095760405162461bcd60e51b8152600401610228906115f7565b6000610f168360f861153d565b6001901b841791505092915050565b6000610f2f611477565b610f37611477565b60008051602061169a833981519152610f528188888861102e565b60018b01805463ffffffff60601b1916600160601b4263ffffffff1602179055604080516001600160a01b03808d1682528b16602082015290810189905292965090945092507f2afbde4d47160a9c5de25b0df88d5b83e705286f2a447cac162db5e99ad6f5d29060600160405180910390a1610fd188858585610986565b5050505050505050565b600060088310610ffd5760405162461bcd60e51b8152600401610228906115f7565b600061100985856111e2565b90506000611017848361153d565b9050611024868683611230565b9695505050505050565b6000611038611477565b611040611477565b61104a87866112e4565b865484036110e45761105b87610e47565b61109f576040805180820182528581526000602080830182905283518085019094526001600160a01b038a168452830181905261109a929091906113b8565b6110d9565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526110d991600191906113b8565b9250925092506111d8565b600387015460f81c1561113d576110d9600260405180604001604052808a6000015481526020018781525060405180604001604052806111238c610d09565b6001600160a01b0390811682528b166020909101526113b8565b83875561114a8787610e1c565b61115387610e47565b611197576040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301819052611192929091906113b8565b6111d1565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526111d191600191906113b8565b9250925092505b9450945094915050565b6000600882106112045760405162461bcd60e51b8152600401610228906115f7565b600061121560016340000000611623565b90508061122384601e61163a565b85901c1691505092915050565b6000600883106112525760405162461bcd60e51b8152600401610228906115f7565b61126160016340000000611623565b8211156112a65760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b6044820152606401610228565b60006112b384601e61163a565b6112c260016340000000611623565b901b1990508481166112d585601e61163a565b9390931b909217949350505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7360005b6001840154811015610ad65783600101818154811061132957611329611555565b6000918252602090912001546001600160a01b03908116908416036113a657600084600101828154811061135f5761135f611555565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600384015461139790826113fd565b6003850155610a46828261145a565b806113b08161156b565b915050611308565b60006113c2611477565b6113ca611477565b7f09201c193a07cae1df95ae692cc698685574c942a04514c48a4c3249f38594ff868686604051610e0893929190611584565b60006008821061141f5760405162461bcd60e51b8152600401610228906115f7565b82600061142d8460f861153d565b6001901b199182169190506114438460f061153d565b6001901b1991821691905061075082856000611230565b600382015461146b90826000611230565b82600301819055505050565b60405180604001604052806002906020820280368337509192915050565b508054600082559060005260206000209081019061076291905b808211156114c357600081556001016114af565b5090565b634e487b7160e01b600052602160045260246000fd5b6003811061076257634e487b7160e01b600052602160045260246000fd5b60208101611508836114dd565b91905290565b60006020828403121561152057600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561155057611550611527565b500190565b634e487b7160e01b600052603260045260246000fd5b60006001820161157d5761157d611527565b5060010190565b60a08101611591856114dd565b84825260208083018560005b60028110156115ba5781518352918301919083019060010161159d565b505050606083018460005b60028110156115eb5781516001600160a01b0316835291830191908301906001016115c5565b50505050949350505050565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b60008282101561163557611635611527565b500390565b600081600019048311821515161561165457611654611527565b50029056fed32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ded606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fcd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ca264697066735822122005a48434be4f5e94111d6d06fc627e4729c541be34424a5e0fb455dd1e4422ab64736f6c634300080d0033", + "libraries": { + "LibClaimsMask": "0x9A676e781A523b5d0C0e43731313A708CB607508" + }, + "devdoc": { + "kind": "dev", + "methods": { + "claim(bytes32)": { + "details": "ValidatorManager makes sure that msg.sender is allowed and that claim != bytes32(0) TODO: add signatures for aggregated claims", + "params": { + "_epochHash": "hash of epoch" + } + }, + "finalizeEpoch()": { + "details": "can only be called if challenge period is over" + }, + "getCurrentEpoch()": { + "details": "if phase is input accumulation, then the epoch number is length of finalized epochs array, else there are two non finalized epochs, one awaiting consensus/dispute and another accumulating input", + "returns": { + "_0": "index of current epoch" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "Claim(uint256,address,bytes32)": { + "notice": "claim submitted" + }, + "FinalizeEpoch(uint256,bytes32)": { + "notice": "epoch finalized" + }, + "PhaseChange(uint8)": { + "notice": "phase change" + }, + "ResolveDispute(address,address,bytes32)": { + "notice": "dispute resolved" + } + }, + "kind": "user", + "methods": { + "claim(bytes32)": { + "notice": "claim the result of current epoch" + }, + "finalizeEpoch()": { + "notice": "finalize epoch after timeout" + }, + "getChallengePeriod()": { + "notice": "returns the challenge period in seconds" + }, + "getCurrentEpoch()": { + "notice": "returns index of current (accumulating) epoch" + }, + "getCurrentPhase()": { + "notice": "returns the current phase" + }, + "getInputAccumulationStart()": { + "notice": "returns the input accumulation start timestamp" + }, + "getInputDuration()": { + "notice": "returns the input duration in seconds" + }, + "getSealingEpochTimestamp()": { + "notice": "returns the sealing epoch timestamp" + }, + "getTemplateHash()": { + "notice": "returns the machine's template hash" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/SimpleFaucet.json b/echo-js/deployments/localhost/SimpleFaucet.json new file mode 100644 index 00000000..fb238b34 --- /dev/null +++ b/echo-js/deployments/localhost/SimpleFaucet.json @@ -0,0 +1,114 @@ +{ + "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "abi": [ + { + "constant": true, + "inputs": [ + { + "name": "_address", + "type": "address" + } + ], + "name": "allowedToWithdraw", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "requestTokens", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "tokenInstance", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "waitTime", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "tokenAmount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_tokenInstance", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "transactionHash": "0x7715e966bfe11ddea38d18ff072aec7cc49c6ba811be3d78d6cf1d911ac7ffb3", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "transactionIndex": 0, + "gasUsed": "280767", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xb8498cc0d27b95c9cf3499642a3fe4173e34671919e0fce1148ca39dab794269", + "transactionHash": "0x7715e966bfe11ddea38d18ff072aec7cc49c6ba811be3d78d6cf1d911ac7ffb3", + "logs": [], + "blockNumber": 10, + "cumulativeGasUsed": "280767", + "status": 1, + "byzantium": true + }, + "args": [ + "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" + ], + "numDeployments": 1, + "bytecode": "0x608060405234801561001057600080fd5b506040516020806104758339810180604052602081101561003057600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506103a8806100cd6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80632d291cad1461005c578063359cf2b7146100b8578063658030b3146100c2578063ccca123b1461010c578063eec7faa11461012a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610148565b604051808215151515815260200191505060405180910390f35b6100c06101f5565b005b6100ca610342565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610114610367565b6040518082815260200191505060405180910390f35b61013261036e565b6040518082815260200191505060405180910390f35b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561019a57600190506101f0565b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421015156101eb57600190506101f0565b600090505b919050565b6101fe33610148565b151561020957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3369152d02c7e14af68000006040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156102bb57600080fd5b505af11580156102cf573d6000803e3d6000fd5b505050506040513d60208110156102e557600080fd5b8101908080519060200190929190505050506224ea004201600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6224ea0081565b69152d02c7e14af68000008156fea165627a7a723058201a95fe0177c1cf4bc787a7385da5ab9120c37ac47a5207b31bfe92023fefe3100029", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c80632d291cad1461005c578063359cf2b7146100b8578063658030b3146100c2578063ccca123b1461010c578063eec7faa11461012a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610148565b604051808215151515815260200191505060405180910390f35b6100c06101f5565b005b6100ca610342565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610114610367565b6040518082815260200191505060405180910390f35b61013261036e565b6040518082815260200191505060405180910390f35b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561019a57600190506101f0565b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421015156101eb57600190506101f0565b600090505b919050565b6101fe33610148565b151561020957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3369152d02c7e14af68000006040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156102bb57600080fd5b505af11580156102cf573d6000803e3d6000fd5b505050506040513d60208110156102e557600080fd5b8101908080519060200190929190505050506224ea004201600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6224ea0081565b69152d02c7e14af68000008156fea165627a7a723058201a95fe0177c1cf4bc787a7385da5ab9120c37ac47a5207b31bfe92023fefe3100029", + "devdoc": { + "methods": {} + }, + "userdoc": { + "methods": {} + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/ValidatorManagerFacet.json b/echo-js/deployments/localhost/ValidatorManagerFacet.json new file mode 100644 index 00000000..61c749a9 --- /dev/null +++ b/echo-js/deployments/localhost/ValidatorManagerFacet.json @@ -0,0 +1,294 @@ +{ + "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Result", + "name": "result", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes32[2]", + "name": "claims", + "type": "bytes32[2]" + }, + { + "indexed": false, + "internalType": "address payable[2]", + "name": "validators", + "type": "address[2]" + } + ], + "name": "ClaimReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum Result", + "name": "result", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes32[2]", + "name": "claims", + "type": "bytes32[2]" + }, + { + "indexed": false, + "internalType": "address payable[2]", + "name": "validators", + "type": "address[2]" + } + ], + "name": "DisputeEnded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "claim", + "type": "bytes32" + } + ], + "name": "NewEpoch", + "type": "event" + }, + { + "inputs": [], + "name": "getAgreementMask", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusGoalMask", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentClaim", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxNumValidators", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_sender", + "type": "address" + } + ], + "name": "getNumberOfClaimsByAddress", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getNumberOfClaimsByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + } + ], + "name": "getValidatorIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xaebc401b4231e3cc9c6f419212e677aafabc809d3b7654a46b68f799fc3b0a65", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "transactionIndex": 0, + "gasUsed": "330748", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x88eabc1025619559e6b04dc2a295af2db58c5ea123090e6999d828b28156a77e", + "transactionHash": "0xaebc401b4231e3cc9c6f419212e677aafabc809d3b7654a46b68f799fc3b0a65", + "logs": [], + "blockNumber": 29, + "cumulativeGasUsed": "330748", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "853463bf44733f3d929a32fa4eacb9e6", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Result\",\"name\":\"result\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32[2]\",\"name\":\"claims\",\"type\":\"bytes32[2]\"},{\"indexed\":false,\"internalType\":\"address payable[2]\",\"name\":\"validators\",\"type\":\"address[2]\"}],\"name\":\"ClaimReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum Result\",\"name\":\"result\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32[2]\",\"name\":\"claims\",\"type\":\"bytes32[2]\"},{\"indexed\":false,\"internalType\":\"address payable[2]\",\"name\":\"validators\",\"type\":\"address[2]\"}],\"name\":\"DisputeEnded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"claim\",\"type\":\"bytes32\"}],\"name\":\"NewEpoch\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getAgreementMask\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConsensusGoalMask\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentClaim\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMaxNumValidators\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_sender\",\"type\":\"address\"}],\"name\":\"getNumberOfClaimsByAddress\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNumberOfClaimsByIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"}],\"name\":\"getValidatorIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getAgreementMask()\":{\"returns\":{\"_0\":\"current state of agreement mask\"}},\"getConsensusGoalMask()\":{\"returns\":{\"_0\":\"current consensus goal mask\"}},\"getCurrentClaim()\":{\"returns\":{\"_0\":\"current claim\"}},\"getMaxNumValidators()\":{\"returns\":{\"_0\":\"the maximum number of validators\"}},\"getNumberOfClaimsByAddress(address)\":{\"params\":{\"_sender\":\"validator address\"},\"returns\":{\"_0\":\"#claims\"}},\"getNumberOfClaimsByIndex(uint256)\":{\"params\":{\"_index\":\"the index in validator set\"},\"returns\":{\"_0\":\"#claims\"}},\"getValidatorIndex(address)\":{\"params\":{\"_sender\":\"validator address\"},\"returns\":{\"_0\":\"validator index or revert\"}}},\"version\":1},\"userdoc\":{\"events\":{\"ClaimReceived(uint8,bytes32[2],address[2])\":{\"notice\":\"emitted on Claim received\"},\"DisputeEnded(uint8,bytes32[2],address[2])\":{\"notice\":\"emitted on Dispute end\"},\"NewEpoch(bytes32)\":{\"notice\":\"emitted on new Epoch\"}},\"kind\":\"user\",\"methods\":{\"getAgreementMask()\":{\"notice\":\"get agreement mask\"},\"getConsensusGoalMask()\":{\"notice\":\"get consensus goal mask\"},\"getCurrentClaim()\":{\"notice\":\"get current claim\"},\"getMaxNumValidators()\":{\"notice\":\"get the maximum number of validators defined in validator manager\"},\"getNumberOfClaimsByAddress(address)\":{\"notice\":\"get number of claims the sender has made\"},\"getNumberOfClaimsByIndex(uint256)\":{\"notice\":\"get number of claims by the index in the validator set\"},\"getValidatorIndex(address)\":{\"notice\":\"find the validator and return the index or revert\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/ValidatorManagerFacet.sol\":\"ValidatorManagerFacet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"contracts/IBank.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n// @title Bank interface\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IBank {\\n /// @notice returns the token used internally\\n function getToken() external view returns (IERC20);\\n\\n /// @notice get balance of `_owner`\\n /// @param _owner account owner\\n function balanceOf(address _owner) external view returns (uint256);\\n\\n /// @notice transfer `_value` tokens from bank to `_to`\\n /// @notice decrease the balance of caller by `_value`\\n /// @param _to account that will receive `_value` tokens\\n /// @param _value amount of tokens to be transfered\\n function transferTokens(address _to, uint256 _value) external;\\n\\n /// @notice transfer `_value` tokens from caller to bank\\n /// @notice increase the balance of `_to` by `_value`\\n /// @dev you may need to call `token.approve(bank, _value)`\\n /// @param _to account that will have their balance increased by `_value`\\n /// @param _value amount of tokens to be transfered\\n function depositTokens(address _to, uint256 _value) external;\\n\\n /// @notice `value` tokens were transfered from the bank to `to`\\n /// @notice the balance of `from` was decreased by `value`\\n /// @dev is triggered on any successful call to `transferTokens`\\n /// @param from the account/contract that called `transferTokens` and\\n /// got their balance decreased by `value`\\n /// @param to the one that received `value` tokens from the bank\\n /// @param value amount of tokens that were transfered\\n event Transfer(address indexed from, address to, uint256 value);\\n\\n /// @notice `value` tokens were transfered from `from` to bank\\n /// @notice the balance of `to` was increased by `value`\\n /// @dev is triggered on any successful call to `depositTokens`\\n /// @param from the account/contract that called `depositTokens` and\\n /// transfered `value` tokens to the bank\\n /// @param to the one that got their balance increased by `value`\\n /// @param value amount of tokens that were transfered\\n event Deposit(address from, address indexed to, uint256 value);\\n}\\n\",\"keccak256\":\"0x483dc9b0c26e3a5d43148cf847bd4df2af03438a0d76d60d33549de3ca2dd77d\",\"license\":\"Apache-2.0\"},\"contracts/facets/ValidatorManagerFacet.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager facet\\npragma solidity ^0.8.0;\\n\\nimport {IValidatorManager} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\n\\ncontract ValidatorManagerFacet is IValidatorManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n /// @notice get agreement mask\\n /// @return current state of agreement mask\\n function getAgreementMask() public view returns (uint256) {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.claimsMask.getAgreementMask();\\n }\\n\\n /// @notice get consensus goal mask\\n /// @return current consensus goal mask\\n function getConsensusGoalMask() public view returns (uint256) {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get current claim\\n /// @return current claim\\n function getCurrentClaim() public view override returns (bytes32) {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.currentClaim;\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(address payable _sender)\\n public\\n view\\n returns (uint256)\\n {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.getNumberOfClaimsByAddress(_sender);\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param _sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(address _sender) public view returns (uint256) {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.getValidatorIndex(_sender);\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param _index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(uint256 _index)\\n public\\n view\\n returns (uint256)\\n {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.getNumberOfClaimsByIndex(_index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @return the maximum number of validators\\n function getMaxNumValidators() public view returns (uint256) {\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n return validatorManagerDS.getMaxNumValidators();\\n }\\n}\\n\",\"keccak256\":\"0x10f7fe77f1ed0f1e97927589a8b51128ace21e41fd8e4b757f82ee22a8e92abc\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager interface\\npragma solidity >=0.7.0;\\n\\n// NoConflict - No conflicting claims or consensus\\n// Consensus - All validators had equal claims\\n// Conflict - Claim is conflicting with previous one\\nenum Result {\\n NoConflict,\\n Consensus,\\n Conflict\\n}\\n\\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\\ninterface IValidatorManager {\\n /// @notice get current claim\\n function getCurrentClaim() external view returns (bytes32);\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n}\\n\",\"keccak256\":\"0x7eccbaf15dc80cd402459e8c940b0012fd3d3b8d2882fa13798afe92a9ea3b86\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibClaimsMask.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title ClaimsMask library\\npragma solidity >=0.8.8;\\n\\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\\n// agreement mask and consensus goal mask are not used.\\n\\ntype ClaimsMask is uint256;\\n\\nlibrary LibClaimsMask {\\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\\n\\n /// @notice this function creates a new ClaimsMask variable with value _value\\n /// @param _value the value following the format of ClaimsMask\\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\\n return ClaimsMask.wrap(_value);\\n }\\n\\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\\n /// according to the number of validators\\n /// @param _numValidators the number of validators\\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_numValidators <= 8, \\\"up to 8 validators\\\");\\n uint256 consensusMask = (1 << _numValidators) - 1;\\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\\n }\\n\\n /// @notice this function returns the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (uint256)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 bitmask = (1 << claimsBitLen) - 1;\\n return\\n (ClaimsMask.unwrap(_claimsMask) >>\\n (claimsBitLen * _validatorIndex)) & bitmask;\\n }\\n\\n /// @notice this function increases the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the increase amount\\n function increaseNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\\n }\\n\\n /// @notice this function sets the #claims for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n /// @param _value the set value\\n function setNumClaims(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex,\\n uint256 _value\\n ) internal pure returns (ClaimsMask) {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n require(_value <= ((1 << claimsBitLen) - 1), \\\"ClaimsMask Overflow\\\");\\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\\n (claimsBitLen * _validatorIndex));\\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\\n _claimsMask = ClaimsMask.wrap(\\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\\n );\\n return _claimsMask;\\n }\\n\\n /// @notice get consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function clearAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\\n return ClaimsMask.wrap(clearedMask);\\n }\\n\\n /// @notice get the entire agreement mask\\n /// @param _claimsMask the ClaimsMask value\\n function getAgreementMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\\n }\\n\\n /// @notice check if a validator has already claimed\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (bool)\\n {\\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\\n return\\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\\n 1) != 0;\\n }\\n\\n /// @notice set agreement mask for the specified validator\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\\n return ClaimsMask.wrap(setMask);\\n }\\n\\n /// @notice get the entire consensus goal mask\\n /// @param _claimsMask the ClaimsMask value\\n function getConsensusGoalMask(ClaimsMask _claimsMask)\\n internal\\n pure\\n returns (uint256)\\n {\\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\\n }\\n\\n /// @notice remove validator from the ClaimsMask\\n /// @param _claimsMask the ClaimsMask value\\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\\n internal\\n pure\\n returns (ClaimsMask)\\n {\\n require(_validatorIndex < 8, \\\"index out of range\\\");\\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\\n // remove validator from agreement bitmask\\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from consensus goal mask\\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\\n claimsMaskValue = (claimsMaskValue & zeroMask);\\n // remove validator from #claims\\n return\\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\\n }\\n}\\n\",\"keccak256\":\"0x80b7355ef8d176c87e9c446542c4a7de8ee208601639af8acc23f6854f8f0080\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFeeManager.sol\":{\"content\":\"// Copyright 2022 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Fee Manager library\\npragma solidity ^0.8.0;\\n\\nimport {LibValidatorManager} from \\\"../libraries/LibValidatorManager.sol\\\";\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {IBank} from \\\"../IBank.sol\\\";\\n\\nlibrary LibFeeManager {\\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n using LibClaimsMask for ClaimsMask;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"FeeManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n address owner; // owner of Fee Manager\\n uint256 feePerClaim;\\n IBank bank; // bank that holds the tokens to pay validators\\n bool lock; // reentrancy lock\\n // A bit set used for up to 8 validators.\\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask numClaimsRedeemed;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function onlyOwner(DiamondStorage storage ds) internal view {\\n require(ds.owner == msg.sender, \\\"caller is not the owner\\\");\\n }\\n\\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\\n valIndex\\n );\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n // underflow checked by default with sol0.8\\n // which means if the validator is removed, calling this function will\\n // either return 0 or revert\\n return totalClaims - redeemedClaims;\\n }\\n\\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator\\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\\n internal\\n view\\n returns (uint256)\\n {\\n require(_validator != address(0), \\\"address should not be 0\\\");\\n\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\\n\\n return redeemedClaims;\\n }\\n\\n /// @notice contract owner can reset the value of fee per claim\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _value the new value of fee per claim\\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\\n internal\\n {\\n // before resetting the feePerClaim, pay fees for all validators as per current rates\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n for (\\n uint256 valIndex;\\n valIndex < validatorManagerDS.maxNumValidators;\\n valIndex++\\n ) {\\n address validator = validatorManagerDS.validators[valIndex];\\n if (validator != address(0)) {\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\\n if (nowRedeemingClaims > 0) {\\n ds.numClaimsRedeemed = ds\\n .numClaimsRedeemed\\n .increaseNumClaims(valIndex, nowRedeemingClaims);\\n\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(validator, nowRedeemingClaims);\\n }\\n }\\n }\\n ds.feePerClaim = _value;\\n emit FeePerClaimReset(_value);\\n }\\n\\n /// @notice this function can be called to redeem fees for validators\\n /// @param ds pointer to FeeManager's diamond storage\\n /// @param _validator address of the validator that is redeeming\\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\\n // follow the Checks-Effects-Interactions pattern for security\\n\\n // ** checks **\\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\\n require(nowRedeemingClaims > 0, \\\"nothing to redeem yet\\\");\\n\\n // ** effects **\\n LibValidatorManager.DiamondStorage\\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\\n valIndex,\\n nowRedeemingClaims\\n );\\n\\n // ** interactions **\\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\\n // emit the number of claimed being redeemed, instead of the amount of tokens\\n emit FeeRedeemed(_validator, nowRedeemingClaims);\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param index index of validator to be removed\\n function removeValidator(DiamondStorage storage ds, uint256 index)\\n internal\\n {\\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\\n }\\n\\n /// @notice emitted on resetting feePerClaim\\n event FeePerClaimReset(uint256 value);\\n\\n /// @notice emitted on ERC20 funds redeemed by validator\\n event FeeRedeemed(address validator, uint256 claims);\\n}\\n\",\"keccak256\":\"0xb06531049bb43f957ad6fd40635bbfdd16668bf0cc3dc637f11535122e9ce968\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibValidatorManager.sol\":{\"content\":\"// Copyright 2021 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title Validator Manager library\\npragma solidity ^0.8.0;\\n\\nimport {Result} from \\\"../interfaces/IValidatorManager.sol\\\";\\n\\nimport {LibClaimsMask, ClaimsMask} from \\\"../libraries/LibClaimsMask.sol\\\";\\nimport {LibFeeManager} from \\\"../libraries/LibFeeManager.sol\\\";\\n\\nlibrary LibValidatorManager {\\n using LibClaimsMask for ClaimsMask;\\n using LibFeeManager for LibFeeManager.DiamondStorage;\\n\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"ValidatorManager.diamond.storage\\\");\\n\\n struct DiamondStorage {\\n bytes32 currentClaim; // current claim - first claim of this epoch\\n address payable[] validators; // up to 8 validators\\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\\n // A bit set used for up to 8 validators.\\n // The first 8 bits are used to indicate whom supports the current claim\\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\\n // The following every 30 bits are used to indicate the number of total claims each validator has made\\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\\n ClaimsMask claimsMask;\\n }\\n\\n /// @notice emitted on Claim received\\n event ClaimReceived(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on Dispute end\\n event DisputeEnded(\\n Result result,\\n bytes32[2] claims,\\n address payable[2] validators\\n );\\n\\n /// @notice emitted on new Epoch\\n event NewEpoch(bytes32 claim);\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n /// @notice called when a dispute ends in rollups\\n /// @param ds diamond storage pointer\\n /// @param winner address of dispute winner\\n /// @param loser address of dispute loser\\n /// @param winningClaim the winnning claim\\n /// @return result of dispute being finished\\n function onDisputeEnd(\\n DiamondStorage storage ds,\\n address payable winner,\\n address payable loser,\\n bytes32 winningClaim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n removeValidator(ds, loser);\\n\\n if (winningClaim == ds.currentClaim) {\\n // first claim stood, dont need to update the bitmask\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n // if first claim lost, and other validators have agreed with it\\n // there is a new dispute to be played\\n if (ds.claimsMask.getAgreementMask() != 0) {\\n return\\n emitDisputeEndedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, winningClaim],\\n [getClaimerOfCurrentClaim(ds), winner]\\n );\\n }\\n // else there are no valdiators that agree with losing claim\\n // we can update current claim and check for consensus in case\\n // the winner is the only validator left\\n ds.currentClaim = winningClaim;\\n updateClaimAgreementMask(ds, winner);\\n return\\n isConsensus(ds)\\n ? emitDisputeEndedAndReturn(\\n Result.Consensus,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n )\\n : emitDisputeEndedAndReturn(\\n Result.NoConflict,\\n [winningClaim, bytes32(0)],\\n [winner, payable(0)]\\n );\\n }\\n\\n /// @notice called when a new epoch starts\\n /// @param ds diamond storage pointer\\n /// @return current claim\\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\\n // reward validators who has made the correct claim by increasing their #claims\\n claimFinalizedIncreaseCounts(ds);\\n\\n bytes32 tmpClaim = ds.currentClaim;\\n\\n // clear current claim\\n ds.currentClaim = bytes32(0);\\n // clear validator agreement bit mask\\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\\n\\n emit NewEpoch(tmpClaim);\\n return tmpClaim;\\n }\\n\\n /// @notice called when a claim is received by rollups\\n /// @param ds diamond storage pointer\\n /// @param sender address of sender of that claim\\n /// @param claim claim received by rollups\\n /// @return result of claim, Consensus | NoConflict | Conflict\\n /// @return [currentClaim, conflicting claim] if there is Conflict\\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\\n /// @return [claimer1, claimer2] if there is Conflcit\\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\\n function onClaim(\\n DiamondStorage storage ds,\\n address payable sender,\\n bytes32 claim\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n require(claim != bytes32(0), \\\"empty claim\\\");\\n require(isValidator(ds, sender), \\\"sender not allowed\\\");\\n\\n // require the validator hasn't claimed in the same epoch before\\n uint256 index = getValidatorIndex(ds, sender);\\n require(\\n !ds.claimsMask.alreadyClaimed(index),\\n \\\"sender had claimed in this epoch before\\\"\\n );\\n\\n // cant return because a single claim might mean consensus\\n if (ds.currentClaim == bytes32(0)) {\\n ds.currentClaim = claim;\\n } else if (claim != ds.currentClaim) {\\n return\\n emitClaimReceivedAndReturn(\\n Result.Conflict,\\n [ds.currentClaim, claim],\\n [getClaimerOfCurrentClaim(ds), sender]\\n );\\n }\\n updateClaimAgreementMask(ds, sender);\\n\\n return\\n isConsensus(ds)\\n ? emitClaimReceivedAndReturn(\\n Result.Consensus,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n )\\n : emitClaimReceivedAndReturn(\\n Result.NoConflict,\\n [claim, bytes32(0)],\\n [sender, payable(0)]\\n );\\n }\\n\\n /// @notice emits dispute ended event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitDisputeEndedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit DisputeEnded(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice emits claim received event and then return\\n /// @param result to be emitted and returned\\n /// @param claims to be emitted and returned\\n /// @param validators to be emitted and returned\\n /// @dev this function existis to make code more clear/concise\\n function emitClaimReceivedAndReturn(\\n Result result,\\n bytes32[2] memory claims,\\n address payable[2] memory validators\\n )\\n internal\\n returns (\\n Result,\\n bytes32[2] memory,\\n address payable[2] memory\\n )\\n {\\n emit ClaimReceived(result, claims, validators);\\n return (result, claims, validators);\\n }\\n\\n /// @notice only call this function when a claim has been finalized\\n /// Either a consensus has been reached or challenge period has past\\n /// @param ds pointer to diamond storage\\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n // if a validator agrees with the current claim\\n if ((agreementMask & (1 << i)) != 0) {\\n // increase #claims by 1\\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\\n }\\n }\\n }\\n\\n /// @notice removes a validator\\n /// @param ds diamond storage pointer\\n /// @param validator address of validator to be removed\\n function removeValidator(DiamondStorage storage ds, address validator)\\n internal\\n {\\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\\n .diamondStorage();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (validator == ds.validators[i]) {\\n // put address(0) in validators position\\n ds.validators[i] = payable(0);\\n // remove the validator from ValidatorManager's claimsMask\\n ds.claimsMask = ds.claimsMask.removeValidator(i);\\n // remove the validator from FeeManager's claimsMask (#redeems)\\n feeManagerDS.removeValidator(i);\\n break;\\n }\\n }\\n }\\n\\n /// @notice check if consensus has been reached\\n /// @param ds pointer to diamond storage\\n function isConsensus(DiamondStorage storage ds)\\n internal\\n view\\n returns (bool)\\n {\\n ClaimsMask claimsMask = ds.claimsMask;\\n return\\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\\n }\\n\\n /// @notice get one of the validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @return validator that agreed with current claim\\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\\n internal\\n view\\n returns (address payable)\\n {\\n // TODO: we are always getting the first validator\\n // on the array that agrees with the current claim to enter a dispute\\n // should this be random?\\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (agreementMask & (1 << i) != 0) {\\n return ds.validators[i];\\n }\\n }\\n revert(\\\"Agreeing validator not found\\\");\\n }\\n\\n /// @notice updates mask of validators that agreed with current claim\\n /// @param ds diamond storage pointer\\n /// @param sender address of validator that will be included in mask\\n function updateClaimAgreementMask(\\n DiamondStorage storage ds,\\n address payable sender\\n ) internal {\\n uint256 validatorIndex = getValidatorIndex(ds, sender);\\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\\n }\\n\\n /// @notice check if the sender is a validator\\n /// @param ds pointer to diamond storage\\n /// @param sender sender address\\n function isValidator(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (bool)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return true;\\n }\\n\\n return false;\\n }\\n\\n /// @notice find the validator and return the index or revert\\n /// @param ds pointer to diamond storage\\n /// @param sender validator address\\n /// @return validator index or revert\\n function getValidatorIndex(DiamondStorage storage ds, address sender)\\n internal\\n view\\n returns (uint256)\\n {\\n require(sender != address(0), \\\"address 0\\\");\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (sender == ds.validators[i]) return i;\\n }\\n revert(\\\"validator not found\\\");\\n }\\n\\n /// @notice get number of claims the sender has made\\n /// @param ds pointer to diamond storage\\n /// @param _sender validator address\\n /// @return #claims\\n function getNumberOfClaimsByAddress(\\n DiamondStorage storage ds,\\n address payable _sender\\n ) internal view returns (uint256) {\\n for (uint256 i; i < ds.validators.length; i++) {\\n if (_sender == ds.validators[i]) {\\n return getNumberOfClaimsByIndex(ds, i);\\n }\\n }\\n // if validator not found\\n return 0;\\n }\\n\\n /// @notice get number of claims by the index in the validator set\\n /// @param ds pointer to diamond storage\\n /// @param index the index in validator set\\n /// @return #claims\\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.claimsMask.getNumClaims(index);\\n }\\n\\n /// @notice get the maximum number of validators defined in validator manager\\n /// @param ds pointer to diamond storage\\n /// @return the maximum number of validators\\n function getMaxNumValidators(DiamondStorage storage ds)\\n internal\\n view\\n returns (uint256)\\n {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0xc5c11d8a0f745c785a8ca19b27f3ab232a53ecdab6b179b4d0c5df353690bce5\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610506806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638219fda41161005b5780638219fda4146100c2578063cc8a2451146100d7578063d2992f54146100ea578063f6023815146100f257600080fd5b8063101494ce146100825780631fcc449e1461009c57806355564a70146100af575b600080fd5b61008a6100fa565b60405190815260200160405180910390f35b61008a6100aa3660046103ff565b610139565b61008a6100bd3660046103ff565b61015b565b6000805160206104b18339815191525461008a565b61008a6100e536600461041c565b610176565b61008a610191565b61008a6101cb565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f81c5b91505090565b60006000805160206104b1833981519152610154818461020b565b9392505050565b60006000805160206104b183398151915261015481846102f5565b60006000805160206104b18339815191526101548184610367565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fe546000906000805160206104b183398151915290610133565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f01c60ff16610133565b60006001600160a01b0382166102545760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064015b60405180910390fd5b60005b60018401548110156102b05783600101818154811061027857610278610435565b6000918252602090912001546001600160a01b039081169084160361029e5790506102ef565b806102a881610461565b915050610257565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161024b565b92915050565b6000805b600184015481101561035d5783600101818154811061031a5761031a610435565b6000918252602090912001546001600160a01b039081169084160361034b576103438482610367565b9150506102ef565b8061035581610461565b9150506102f9565b5060009392505050565b600382015460009061015490836000600882106103bb5760405162461bcd60e51b8152602060048201526012602482015271696e646578206f7574206f662072616e676560701b604482015260640161024b565b60006103cc6001634000000061047a565b9050806103da84601e610491565b85901c1691505092915050565b6001600160a01b03811681146103fc57600080fd5b50565b60006020828403121561041157600080fd5b8135610154816103e7565b60006020828403121561042e57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016104735761047361044b565b5060010190565b60008282101561048c5761048c61044b565b500390565b60008160001904831182151516156104ab576104ab61044b565b50029056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fca26469706673582212202b700a34055d7bd57f021e5c896711657796122af288967d1a632e9fce47fadb64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638219fda41161005b5780638219fda4146100c2578063cc8a2451146100d7578063d2992f54146100ea578063f6023815146100f257600080fd5b8063101494ce146100825780631fcc449e1461009c57806355564a70146100af575b600080fd5b61008a6100fa565b60405190815260200160405180910390f35b61008a6100aa3660046103ff565b610139565b61008a6100bd3660046103ff565b61015b565b6000805160206104b18339815191525461008a565b61008a6100e536600461041c565b610176565b61008a610191565b61008a6101cb565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f81c5b91505090565b60006000805160206104b1833981519152610154818461020b565b9392505050565b60006000805160206104b183398151915261015481846102f5565b60006000805160206104b18339815191526101548184610367565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fe546000906000805160206104b183398151915290610133565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f01c60ff16610133565b60006001600160a01b0382166102545760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064015b60405180910390fd5b60005b60018401548110156102b05783600101818154811061027857610278610435565b6000918252602090912001546001600160a01b039081169084160361029e5790506102ef565b806102a881610461565b915050610257565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161024b565b92915050565b6000805b600184015481101561035d5783600101818154811061031a5761031a610435565b6000918252602090912001546001600160a01b039081169084160361034b576103438482610367565b9150506102ef565b8061035581610461565b9150506102f9565b5060009392505050565b600382015460009061015490836000600882106103bb5760405162461bcd60e51b8152602060048201526012602482015271696e646578206f7574206f662072616e676560701b604482015260640161024b565b60006103cc6001634000000061047a565b9050806103da84601e610491565b85901c1691505092915050565b6001600160a01b03811681146103fc57600080fd5b50565b60006020828403121561041157600080fd5b8135610154816103e7565b60006020828403121561042e57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016104735761047361044b565b5060010190565b60008282101561048c5761048c61044b565b500390565b60008160001904831182151516156104ab576104ab61044b565b50029056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fca26469706673582212202b700a34055d7bd57f021e5c896711657796122af288967d1a632e9fce47fadb64736f6c634300080d0033", + "libraries": { + "LibClaimsMask": "0x9A676e781A523b5d0C0e43731313A708CB607508" + }, + "devdoc": { + "kind": "dev", + "methods": { + "getAgreementMask()": { + "returns": { + "_0": "current state of agreement mask" + } + }, + "getConsensusGoalMask()": { + "returns": { + "_0": "current consensus goal mask" + } + }, + "getCurrentClaim()": { + "returns": { + "_0": "current claim" + } + }, + "getMaxNumValidators()": { + "returns": { + "_0": "the maximum number of validators" + } + }, + "getNumberOfClaimsByAddress(address)": { + "params": { + "_sender": "validator address" + }, + "returns": { + "_0": "#claims" + } + }, + "getNumberOfClaimsByIndex(uint256)": { + "params": { + "_index": "the index in validator set" + }, + "returns": { + "_0": "#claims" + } + }, + "getValidatorIndex(address)": { + "params": { + "_sender": "validator address" + }, + "returns": { + "_0": "validator index or revert" + } + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "ClaimReceived(uint8,bytes32[2],address[2])": { + "notice": "emitted on Claim received" + }, + "DisputeEnded(uint8,bytes32[2],address[2])": { + "notice": "emitted on Dispute end" + }, + "NewEpoch(bytes32)": { + "notice": "emitted on new Epoch" + } + }, + "kind": "user", + "methods": { + "getAgreementMask()": { + "notice": "get agreement mask" + }, + "getConsensusGoalMask()": { + "notice": "get consensus goal mask" + }, + "getCurrentClaim()": { + "notice": "get current claim" + }, + "getMaxNumValidators()": { + "notice": "get the maximum number of validators defined in validator manager" + }, + "getNumberOfClaimsByAddress(address)": { + "notice": "get number of claims the sender has made" + }, + "getNumberOfClaimsByIndex(uint256)": { + "notice": "get number of claims by the index in the validator set" + }, + "getValidatorIndex(address)": { + "notice": "find the validator and return the index or revert" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/WorkerAuthManagerImpl.json b/echo-js/deployments/localhost/WorkerAuthManagerImpl.json new file mode 100644 index 00000000..a3e633b8 --- /dev/null +++ b/echo-js/deployments/localhost/WorkerAuthManagerImpl.json @@ -0,0 +1,255 @@ +{ + "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_workerManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Authorization", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Deauthorization", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "authorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "deauthorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "isAuthorized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x7a4792ed907c93f174bd72de48d6e9c24dc679b57bbb861923aeb90a6756295b", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", + "transactionIndex": 0, + "gasUsed": "425367", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf0fd01a7d8a70fa3cc56b023076be1c3a0dd4d2386e00560975abb5c52b43624", + "transactionHash": "0x7a4792ed907c93f174bd72de48d6e9c24dc679b57bbb861923aeb90a6756295b", + "logs": [], + "blockNumber": 6, + "cumulativeGasUsed": "425367", + "status": 1, + "byzantium": true + }, + "args": [ + "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" + ], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"}],\"name\":\"Authorization\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"}],\"name\":\"Deauthorization\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"authorize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"deauthorize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"authorize(address,address)\":{\"params\":{\"_dappAddress\":\"address of the dapp that permission will be given to\",\"_workerAddress\":\"address of the worker node to given permission\"}},\"isAuthorized(address,address)\":{\"params\":{\"_dappAddress\":\"address of the DApp\",\"_workerAddress\":\"address of the worker\"}}},\"stateVariables\":{\"permissions\":{\"details\":\"permissions keyed by hash(user, worker, dapp)\"}},\"version\":1},\"userdoc\":{\"events\":{\"Authorization(address,address,address)\":{\"notice\":\"A DApp has been authorized by a user for a worker\"},\"Deauthorization(address,address,address)\":{\"notice\":\"A DApp has been deauthorized by a user for a worker\"}},\"kind\":\"user\",\"methods\":{\"authorize(address,address)\":{\"notice\":\"Gives worker permission to act on a DApp\"},\"isAuthorized(address,address)\":{\"notice\":\"Returns is the dapp is authorized to be called by that worker\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/WorkerAuthManagerImpl.sol\":\"WorkerAuthManagerImpl\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/WorkerAuthManager.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerAuthManager\\n/// @author Danilo Tuler\\npragma solidity >=0.7.0;\\n\\ninterface WorkerAuthManager {\\n /// @notice Gives worker permission to act on a DApp\\n /// @param _workerAddress address of the worker node to given permission\\n /// @param _dappAddress address of the dapp that permission will be given to\\n function authorize(address _workerAddress, address _dappAddress) external;\\n\\n /// @notice Removes worker's permission to act on a DApp\\n /// @param _workerAddress address of the proxy that will lose permission\\n /// @param _dappAddresses addresses of dapps that will lose permission\\n function deauthorize(address _workerAddress, address _dappAddresses)\\n external;\\n\\n /// @notice Returns is the dapp is authorized to be called by that worker\\n /// @param _workerAddress address of the worker\\n /// @param _dappAddress address of the DApp\\n function isAuthorized(address _workerAddress, address _dappAddress)\\n external\\n view\\n returns (bool);\\n\\n /// @notice Get the owner of the worker node\\n /// @param workerAddress address of the worker node\\n function getOwner(address workerAddress) external view returns (address);\\n\\n /// @notice A DApp has been authorized by a user for a worker\\n event Authorization(\\n address indexed user,\\n address indexed worker,\\n address indexed dapp\\n );\\n\\n /// @notice A DApp has been deauthorized by a user for a worker\\n event Deauthorization(\\n address indexed user,\\n address indexed worker,\\n address indexed dapp\\n );\\n}\\n\",\"keccak256\":\"0xb69b2fc75aae609d5a4098b77fb8f48dc87ff8073a8a3b70c0261af5f62f36db\",\"license\":\"Apache-2.0\"},\"contracts/WorkerAuthManagerImpl.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerAuthManagerImpl\\n/// @author Danilo Tuler\\npragma solidity ^0.8.0;\\n\\nimport \\\"./WorkerManager.sol\\\";\\nimport \\\"./WorkerAuthManager.sol\\\";\\n\\ncontract WorkerAuthManagerImpl is WorkerAuthManager {\\n WorkerManager workerManager;\\n\\n /// @dev permissions keyed by hash(user, worker, dapp)\\n mapping(bytes32 => bool) private permissions;\\n\\n constructor(address _workerManager) {\\n workerManager = WorkerManager(_workerManager);\\n }\\n\\n modifier onlyByOwner(address _workerAddress) {\\n require(\\n workerManager.getOwner(_workerAddress) == msg.sender,\\n \\\"worker not hired by sender\\\"\\n );\\n _;\\n }\\n\\n function getAuthorizationKey(\\n address _user,\\n address _worker,\\n address _dapp\\n ) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_user, _worker, _dapp));\\n }\\n\\n function authorize(address _workerAddress, address _dappAddress)\\n public\\n override\\n onlyByOwner(_workerAddress)\\n {\\n bytes32 key = getAuthorizationKey(\\n msg.sender,\\n _workerAddress,\\n _dappAddress\\n );\\n require(permissions[key] == false, \\\"dapp already authorized\\\");\\n\\n // record authorization from that user\\n permissions[key] = true;\\n\\n // emit event\\n emit Authorization(msg.sender, _workerAddress, _dappAddress);\\n }\\n\\n function deauthorize(address _workerAddress, address _dappAddress)\\n public\\n override\\n onlyByOwner(_workerAddress)\\n {\\n bytes32 key = getAuthorizationKey(\\n msg.sender,\\n _workerAddress,\\n _dappAddress\\n );\\n require(permissions[key] == true, \\\"dapp not authorized\\\");\\n\\n // record deauthorization from that user\\n permissions[key] = false;\\n\\n // emit event\\n emit Deauthorization(msg.sender, _workerAddress, _dappAddress);\\n }\\n\\n function isAuthorized(address _workerAddress, address _dappAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return\\n permissions[getAuthorizationKey(\\n workerManager.getOwner(_workerAddress),\\n _workerAddress,\\n _dappAddress\\n )];\\n }\\n\\n function getOwner(address _workerAddress)\\n public\\n override\\n view\\n returns (address)\\n {\\n return workerManager.getOwner(_workerAddress);\\n }\\n\\n /*\\n // XXX: we can't do this because the worker need to accept the job before receiving an authorization\\n function hireAndAuthorize(\\n address payable _workerAddress,\\n address _dappAddress\\n ) public override payable {\\n workerManager.hire(_workerAddress);\\n authorize(_workerAddress, _dappAddress);\\n }\\n */\\n}\\n\",\"keccak256\":\"0x3c97f9e58f8190f0a081cf753c47dec51806ec4994ed66608e73522086ae0785\",\"license\":\"Apache-2.0\"},\"contracts/WorkerManager.sol\":{\"content\":\"// Copyright 2010 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerManager\\n/// @author Danilo Tuler\\npragma solidity >=0.7.0;\\n\\ninterface WorkerManager {\\n /// @notice Returns true if worker node is available\\n /// @param workerAddress address of the worker node\\n function isAvailable(address workerAddress) external view returns (bool);\\n\\n /// @notice Returns true if worker node is pending\\n /// @param workerAddress address of the worker node\\n function isPending(address workerAddress) external view returns (bool);\\n\\n /// @notice Get the owner of the worker node\\n /// @param workerAddress address of the worker node\\n function getOwner(address workerAddress) external view returns (address);\\n\\n /// @notice Get the user of the worker node, which may not be the owner yet, or how was the previous owner of a retired node\\n function getUser(address workerAddress) external view returns (address);\\n\\n /// @notice Returns true if worker node is owned by some user\\n function isOwned(address workerAddress) external view returns (bool);\\n\\n /// @notice Asks the worker to work for the sender. Sender needs to pay something.\\n /// @param workerAddress address of the worker\\n function hire(address payable workerAddress) external payable;\\n\\n /// @notice Called by the worker to accept the job\\n function acceptJob() external;\\n\\n /// @notice Called by the worker to reject a job offer\\n function rejectJob() external payable;\\n\\n /// @notice Called by the user to cancel a job offer\\n /// @param workerAddress address of the worker node\\n function cancelHire(address workerAddress) external;\\n\\n /// @notice Called by the user to retire his worker.\\n /// @param workerAddress address of the worker to be retired\\n /// @dev this also removes all authorizations in place\\n function retire(address payable workerAddress) external;\\n\\n /// @notice Returns true if worker node was retired by its owner\\n function isRetired(address workerAddress) external view returns (bool);\\n\\n /// @notice Events signalling every state transition\\n event JobOffer(address indexed worker, address indexed user);\\n event JobAccepted(address indexed worker, address indexed user);\\n event JobRejected(address indexed worker, address indexed user);\\n event Retired(address indexed worker, address indexed user);\\n}\\n\",\"keccak256\":\"0xb93bac1de98b3fb44421c2498f11bcd246795c7cffeeebb535a046e88c303410\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506040516106dc3803806106dc83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610082565b600060208284031215610065578081fd5b81516001600160a01b038116811461007b578182fd5b9392505050565b61064b806100916000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632bef45951461005157806365e4ad9e146100665780636d892f7e1461008e578063fa544161146100a1575b600080fd5b61006461005f3660046105c5565b6100cc565b005b6100796100743660046105c5565b61026f565b60405190151581526020015b60405180910390f35b61006461009c3660046105c5565b610318565b6100b46100af366004610586565b6104ad565b6040516001600160a01b039091168152602001610085565b60005460405163fa54416160e01b81526001600160a01b0380851660048301528492339291169063fa5441619060240160206040518083038186803b15801561011457600080fd5b505afa158015610128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014c91906105a9565b6001600160a01b0316146101a75760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e64657200000000000060448201526064015b60405180910390fd5b60006101b4338585610531565b60008181526001602052604090205490915060ff16156102165760405162461bcd60e51b815260206004820152601760248201527f6461707020616c726561647920617574686f72697a6564000000000000000000604482015260640161019e565b6000818152600160208190526040808320805460ff1916909217909155516001600160a01b03808616929087169133917fde756a416a233cdb16c23a1fa5dcb3113164968df8607e0a4eeca25974b96e0391a450505050565b6000805460405163fa54416160e01b81526001600160a01b03858116600483015260019284926102fd929091169063fa5441619060240160206040518083038186803b1580156102be57600080fd5b505afa1580156102d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f691906105a9565b8686610531565b815260208101919091526040016000205460ff169392505050565b60005460405163fa54416160e01b81526001600160a01b0380851660048301528492339291169063fa5441619060240160206040518083038186803b15801561036057600080fd5b505afa158015610374573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039891906105a9565b6001600160a01b0316146103ee5760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e646572000000000000604482015260640161019e565b60006103fb338585610531565b60008181526001602081905260409091205491925060ff90911615151461045a5760405162461bcd60e51b815260206004820152601360248201527219185c1c081b9bdd08185d5d1a1bdc9a5e9959606a1b604482015260640161019e565b600081815260016020526040808220805460ff19169055516001600160a01b03808616929087169133917f4d2275ddb8a6d9c36c95476c2eaf9746c1785b4ab76a99719fd647b36da46cee91a450505050565b6000805460405163fa54416160e01b81526001600160a01b0384811660048301529091169063fa5441619060240160206040518083038186803b1580156104f357600080fd5b505afa158015610507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052b91906105a9565b92915050565b6040516bffffffffffffffffffffffff19606085811b8216602084015284811b8216603484015283901b166048820152600090605c016040516020818303038152906040528051906020012090509392505050565b600060208284031215610597578081fd5b81356105a2816105fd565b9392505050565b6000602082840312156105ba578081fd5b81516105a2816105fd565b600080604083850312156105d7578081fd5b82356105e2816105fd565b915060208301356105f2816105fd565b809150509250929050565b6001600160a01b038116811461061257600080fd5b5056fea2646970667358221220b1862e5175b3b9a9fc5da21d120da98326517836ca159b01590210084513622d64736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632bef45951461005157806365e4ad9e146100665780636d892f7e1461008e578063fa544161146100a1575b600080fd5b61006461005f3660046105c5565b6100cc565b005b6100796100743660046105c5565b61026f565b60405190151581526020015b60405180910390f35b61006461009c3660046105c5565b610318565b6100b46100af366004610586565b6104ad565b6040516001600160a01b039091168152602001610085565b60005460405163fa54416160e01b81526001600160a01b0380851660048301528492339291169063fa5441619060240160206040518083038186803b15801561011457600080fd5b505afa158015610128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014c91906105a9565b6001600160a01b0316146101a75760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e64657200000000000060448201526064015b60405180910390fd5b60006101b4338585610531565b60008181526001602052604090205490915060ff16156102165760405162461bcd60e51b815260206004820152601760248201527f6461707020616c726561647920617574686f72697a6564000000000000000000604482015260640161019e565b6000818152600160208190526040808320805460ff1916909217909155516001600160a01b03808616929087169133917fde756a416a233cdb16c23a1fa5dcb3113164968df8607e0a4eeca25974b96e0391a450505050565b6000805460405163fa54416160e01b81526001600160a01b03858116600483015260019284926102fd929091169063fa5441619060240160206040518083038186803b1580156102be57600080fd5b505afa1580156102d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f691906105a9565b8686610531565b815260208101919091526040016000205460ff169392505050565b60005460405163fa54416160e01b81526001600160a01b0380851660048301528492339291169063fa5441619060240160206040518083038186803b15801561036057600080fd5b505afa158015610374573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039891906105a9565b6001600160a01b0316146103ee5760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e646572000000000000604482015260640161019e565b60006103fb338585610531565b60008181526001602081905260409091205491925060ff90911615151461045a5760405162461bcd60e51b815260206004820152601360248201527219185c1c081b9bdd08185d5d1a1bdc9a5e9959606a1b604482015260640161019e565b600081815260016020526040808220805460ff19169055516001600160a01b03808616929087169133917f4d2275ddb8a6d9c36c95476c2eaf9746c1785b4ab76a99719fd647b36da46cee91a450505050565b6000805460405163fa54416160e01b81526001600160a01b0384811660048301529091169063fa5441619060240160206040518083038186803b1580156104f357600080fd5b505afa158015610507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052b91906105a9565b92915050565b6040516bffffffffffffffffffffffff19606085811b8216602084015284811b8216603484015283901b166048820152600090605c016040516020818303038152906040528051906020012090509392505050565b600060208284031215610597578081fd5b81356105a2816105fd565b9392505050565b6000602082840312156105ba578081fd5b81516105a2816105fd565b600080604083850312156105d7578081fd5b82356105e2816105fd565b915060208301356105f2816105fd565b809150509250929050565b6001600160a01b038116811461061257600080fd5b5056fea2646970667358221220b1862e5175b3b9a9fc5da21d120da98326517836ca159b01590210084513622d64736f6c63430008040033", + "devdoc": { + "kind": "dev", + "methods": { + "authorize(address,address)": { + "params": { + "_dappAddress": "address of the dapp that permission will be given to", + "_workerAddress": "address of the worker node to given permission" + } + }, + "isAuthorized(address,address)": { + "params": { + "_dappAddress": "address of the DApp", + "_workerAddress": "address of the worker" + } + } + }, + "stateVariables": { + "permissions": { + "details": "permissions keyed by hash(user, worker, dapp)" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "Authorization(address,address,address)": { + "notice": "A DApp has been authorized by a user for a worker" + }, + "Deauthorization(address,address,address)": { + "notice": "A DApp has been deauthorized by a user for a worker" + } + }, + "kind": "user", + "methods": { + "authorize(address,address)": { + "notice": "Gives worker permission to act on a DApp" + }, + "isAuthorized(address,address)": { + "notice": "Returns is the dapp is authorized to be called by that worker" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 63, + "contract": "contracts/WorkerAuthManagerImpl.sol:WorkerAuthManagerImpl", + "label": "workerManager", + "offset": 0, + "slot": "0", + "type": "t_contract(WorkerManager)343" + }, + { + "astId": 68, + "contract": "contracts/WorkerAuthManagerImpl.sol:WorkerAuthManagerImpl", + "label": "permissions", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_bool)" + } + ], + "types": { + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(WorkerManager)343": { + "encoding": "inplace", + "label": "contract WorkerManager", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + } + } + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/WorkerManagerAuthManagerImpl.json b/echo-js/deployments/localhost/WorkerManagerAuthManagerImpl.json new file mode 100644 index 00000000..f2fcde3b --- /dev/null +++ b/echo-js/deployments/localhost/WorkerManagerAuthManagerImpl.json @@ -0,0 +1,553 @@ +{ + "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Authorization", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + } + ], + "name": "Deauthorization", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobOffer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobRejected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "Retired", + "type": "event" + }, + { + "inputs": [], + "name": "acceptJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "authorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "cancelHire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "deauthorize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getUser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "hire", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "hireAndAuthorize", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappAddress", + "type": "address" + } + ], + "name": "isAuthorized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isAvailable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isOwned", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isPending", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isRetired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rejectJob", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "retire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xe98b661726674730ed6df15d10b58950dd05412308a6300f0d49a0ca9bdb0d5a", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F", + "transactionIndex": 0, + "gasUsed": "773218", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x9376e753aefd6e06c9604b345db1e9c4ee7d3d020f0a863ed2d819767d7c8d5e", + "transactionHash": "0xe98b661726674730ed6df15d10b58950dd05412308a6300f0d49a0ca9bdb0d5a", + "logs": [], + "blockNumber": 7, + "cumulativeGasUsed": "773218", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"}],\"name\":\"Authorization\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"}],\"name\":\"Deauthorization\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"JobAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"JobOffer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"JobRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"Retired\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"authorize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"cancelHire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"deauthorize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"getUser\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"hire\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"hireAndAuthorize\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappAddress\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workerAddress\",\"type\":\"address\"}],\"name\":\"isAvailable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"isOwned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workerAddress\",\"type\":\"address\"}],\"name\":\"isPending\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"isRetired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rejectJob\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"retire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"authorize(address,address)\":{\"params\":{\"_dappAddress\":\"address of the dapp that permission will be given to\",\"_workerAddress\":\"address of the worker node to given permission\"}},\"isAuthorized(address,address)\":{\"params\":{\"_dappAddress\":\"address of the DApp\",\"_workerAddress\":\"address of the worker\"}},\"isAvailable(address)\":{\"params\":{\"workerAddress\":\"address of the worker node\"}},\"isPending(address)\":{\"params\":{\"workerAddress\":\"address of the worker node\"}}},\"stateVariables\":{\"MAXIMUM_FUNDING\":{\"details\":\"transfers bigger than maximum value should be done directly\"},\"MINIMUM_FUNDING\":{\"details\":\"user can only hire a worker if he sends more than minimum value\"},\"permissions\":{\"details\":\"permissions keyed by hash(user, worker, dapp)\"},\"stateOf\":{\"details\":\"mapping from worker to its internal state\"},\"userOf\":{\"details\":\"mapping from worker to its user\"}},\"version\":1},\"userdoc\":{\"events\":{\"Authorization(address,address,address)\":{\"notice\":\"A DApp has been authorized by a user for a worker\"},\"Deauthorization(address,address,address)\":{\"notice\":\"A DApp has been deauthorized by a user for a worker\"},\"JobOffer(address,address)\":{\"notice\":\"Events signalling every state transition\"}},\"kind\":\"user\",\"methods\":{\"acceptJob()\":{\"notice\":\"Called by the worker to accept the job\"},\"authorize(address,address)\":{\"notice\":\"Gives worker permission to act on a DApp\"},\"isAuthorized(address,address)\":{\"notice\":\"Returns is the dapp is authorized to be called by that worker\"},\"isAvailable(address)\":{\"notice\":\"Returns true if worker node is available\"},\"isPending(address)\":{\"notice\":\"Returns true if worker node is pending\"},\"rejectJob()\":{\"notice\":\"Called by the worker to reject a job offer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/WorkerManagerAuthManagerImpl.sol\":\"WorkerManagerAuthManagerImpl\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/WorkerAuthManager.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerAuthManager\\n/// @author Danilo Tuler\\npragma solidity >=0.7.0;\\n\\ninterface WorkerAuthManager {\\n /// @notice Gives worker permission to act on a DApp\\n /// @param _workerAddress address of the worker node to given permission\\n /// @param _dappAddress address of the dapp that permission will be given to\\n function authorize(address _workerAddress, address _dappAddress) external;\\n\\n /// @notice Removes worker's permission to act on a DApp\\n /// @param _workerAddress address of the proxy that will lose permission\\n /// @param _dappAddresses addresses of dapps that will lose permission\\n function deauthorize(address _workerAddress, address _dappAddresses)\\n external;\\n\\n /// @notice Returns is the dapp is authorized to be called by that worker\\n /// @param _workerAddress address of the worker\\n /// @param _dappAddress address of the DApp\\n function isAuthorized(address _workerAddress, address _dappAddress)\\n external\\n view\\n returns (bool);\\n\\n /// @notice Get the owner of the worker node\\n /// @param workerAddress address of the worker node\\n function getOwner(address workerAddress) external view returns (address);\\n\\n /// @notice A DApp has been authorized by a user for a worker\\n event Authorization(\\n address indexed user,\\n address indexed worker,\\n address indexed dapp\\n );\\n\\n /// @notice A DApp has been deauthorized by a user for a worker\\n event Deauthorization(\\n address indexed user,\\n address indexed worker,\\n address indexed dapp\\n );\\n}\\n\",\"keccak256\":\"0xb69b2fc75aae609d5a4098b77fb8f48dc87ff8073a8a3b70c0261af5f62f36db\",\"license\":\"Apache-2.0\"},\"contracts/WorkerManager.sol\":{\"content\":\"// Copyright 2010 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerManager\\n/// @author Danilo Tuler\\npragma solidity >=0.7.0;\\n\\ninterface WorkerManager {\\n /// @notice Returns true if worker node is available\\n /// @param workerAddress address of the worker node\\n function isAvailable(address workerAddress) external view returns (bool);\\n\\n /// @notice Returns true if worker node is pending\\n /// @param workerAddress address of the worker node\\n function isPending(address workerAddress) external view returns (bool);\\n\\n /// @notice Get the owner of the worker node\\n /// @param workerAddress address of the worker node\\n function getOwner(address workerAddress) external view returns (address);\\n\\n /// @notice Get the user of the worker node, which may not be the owner yet, or how was the previous owner of a retired node\\n function getUser(address workerAddress) external view returns (address);\\n\\n /// @notice Returns true if worker node is owned by some user\\n function isOwned(address workerAddress) external view returns (bool);\\n\\n /// @notice Asks the worker to work for the sender. Sender needs to pay something.\\n /// @param workerAddress address of the worker\\n function hire(address payable workerAddress) external payable;\\n\\n /// @notice Called by the worker to accept the job\\n function acceptJob() external;\\n\\n /// @notice Called by the worker to reject a job offer\\n function rejectJob() external payable;\\n\\n /// @notice Called by the user to cancel a job offer\\n /// @param workerAddress address of the worker node\\n function cancelHire(address workerAddress) external;\\n\\n /// @notice Called by the user to retire his worker.\\n /// @param workerAddress address of the worker to be retired\\n /// @dev this also removes all authorizations in place\\n function retire(address payable workerAddress) external;\\n\\n /// @notice Returns true if worker node was retired by its owner\\n function isRetired(address workerAddress) external view returns (bool);\\n\\n /// @notice Events signalling every state transition\\n event JobOffer(address indexed worker, address indexed user);\\n event JobAccepted(address indexed worker, address indexed user);\\n event JobRejected(address indexed worker, address indexed user);\\n event Retired(address indexed worker, address indexed user);\\n}\\n\",\"keccak256\":\"0xb93bac1de98b3fb44421c2498f11bcd246795c7cffeeebb535a046e88c303410\",\"license\":\"Apache-2.0\"},\"contracts/WorkerManagerAuthManagerImpl.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerManagerAuthManagerImpl\\n/// @author Danilo Tuler\\npragma solidity ^0.8.0;\\n\\nimport \\\"./WorkerManager.sol\\\";\\nimport \\\"./WorkerAuthManager.sol\\\";\\n\\ncontract WorkerManagerAuthManagerImpl is WorkerManager, WorkerAuthManager {\\n /// @dev user can only hire a worker if he sends more than minimum value\\n uint256 constant MINIMUM_FUNDING = 0.001 ether;\\n\\n /// @dev transfers bigger than maximum value should be done directly\\n uint256 constant MAXIMUM_FUNDING = 3 ether;\\n\\n /// @notice A worker can be in 4 different states, starting from Available\\n enum WorkerState {Available, Pending, Owned, Retired}\\n\\n /// @dev mapping from worker to its user\\n mapping(address => address payable) private userOf;\\n\\n /// @dev mapping from worker to its internal state\\n mapping(address => WorkerState) private stateOf;\\n\\n /// @dev permissions keyed by hash(user, worker, dapp)\\n mapping(bytes32 => bool) private permissions;\\n\\n function isAvailable(address workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[workerAddress] == WorkerState.Available;\\n }\\n\\n function isPending(address workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[workerAddress] == WorkerState.Pending;\\n }\\n\\n function getOwner(address _workerAddress)\\n public\\n override(WorkerManager, WorkerAuthManager)\\n view\\n returns (address)\\n {\\n return\\n stateOf[_workerAddress] == WorkerState.Owned\\n ? userOf[_workerAddress]\\n : address(0);\\n }\\n\\n function getUser(address _workerAddress)\\n public\\n override\\n view\\n returns (address)\\n {\\n return userOf[_workerAddress];\\n }\\n\\n function isOwned(address _workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[_workerAddress] == WorkerState.Owned;\\n }\\n\\n function hire(address payable _workerAddress) public override payable {\\n require(isAvailable(_workerAddress), \\\"worker is not available\\\");\\n require(_workerAddress != address(0), \\\"worker address can not be 0x0\\\");\\n require(msg.value >= MINIMUM_FUNDING, \\\"funding below minimum\\\");\\n require(msg.value <= MAXIMUM_FUNDING, \\\"funding above maximum\\\");\\n\\n // set owner\\n userOf[_workerAddress] = payable(msg.sender);\\n\\n // change state\\n stateOf[_workerAddress] = WorkerState.Pending;\\n\\n // transfer ether to worker\\n _workerAddress.transfer(msg.value);\\n\\n // emit event\\n emit JobOffer(_workerAddress, msg.sender);\\n }\\n\\n function acceptJob() public override {\\n require(\\n stateOf[msg.sender] == WorkerState.Pending,\\n \\\"worker not is not in pending state\\\"\\n );\\n\\n // change state\\n stateOf[msg.sender] = WorkerState.Owned;\\n // from now on getOwner will return the user\\n\\n // emit event\\n emit JobAccepted(msg.sender, userOf[msg.sender]);\\n }\\n\\n function rejectJob() public override payable {\\n require(\\n userOf[msg.sender] != address(0),\\n \\\"worker does not have a job offer\\\"\\n );\\n\\n address payable owner = userOf[msg.sender];\\n\\n // reset hirer back to null\\n userOf[msg.sender] = payable(address(0));\\n\\n // change state\\n stateOf[msg.sender] = WorkerState.Available;\\n\\n // return the money\\n owner.transfer(msg.value);\\n\\n // emit event\\n emit JobRejected(msg.sender, userOf[msg.sender]);\\n }\\n\\n function cancelHire(address _workerAddress) public override {\\n require(\\n userOf[_workerAddress] == msg.sender,\\n \\\"only hirer can cancel the offer\\\"\\n );\\n\\n // change state\\n stateOf[_workerAddress] = WorkerState.Retired;\\n\\n // emit event\\n emit Retired(_workerAddress, msg.sender);\\n }\\n\\n function retire(address payable _workerAddress) public override {\\n require(\\n stateOf[_workerAddress] == WorkerState.Owned,\\n \\\"worker not owned\\\"\\n );\\n require(\\n userOf[_workerAddress] == msg.sender,\\n \\\"only owner can retire worker\\\"\\n );\\n\\n // change state\\n stateOf[_workerAddress] = WorkerState.Retired;\\n\\n // emit event\\n emit Retired(_workerAddress, msg.sender);\\n }\\n\\n function isRetired(address _workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[_workerAddress] == WorkerState.Retired;\\n }\\n\\n modifier onlyByUser(address _workerAddress) {\\n require(\\n getUser(_workerAddress) == msg.sender,\\n \\\"worker not hired by sender\\\"\\n );\\n _;\\n }\\n\\n function getAuthorizationKey(\\n address _user,\\n address _worker,\\n address _dapp\\n ) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_user, _worker, _dapp));\\n }\\n\\n function authorize(address _workerAddress, address _dappAddress)\\n public\\n override\\n onlyByUser(_workerAddress)\\n {\\n bytes32 key = getAuthorizationKey(\\n msg.sender,\\n _workerAddress,\\n _dappAddress\\n );\\n require(permissions[key] == false, \\\"dapp already authorized\\\");\\n\\n // record authorization from that user\\n permissions[key] = true;\\n\\n // emit event\\n emit Authorization(msg.sender, _workerAddress, _dappAddress);\\n }\\n\\n function deauthorize(address _workerAddress, address _dappAddress)\\n public\\n override\\n onlyByUser(_workerAddress)\\n {\\n bytes32 key = getAuthorizationKey(\\n msg.sender,\\n _workerAddress,\\n _dappAddress\\n );\\n require(permissions[key] == true, \\\"dapp not authorized\\\");\\n\\n // record deauthorization from that user\\n permissions[key] = false;\\n\\n // emit event\\n emit Deauthorization(msg.sender, _workerAddress, _dappAddress);\\n }\\n\\n function isAuthorized(address _workerAddress, address _dappAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return\\n permissions[getAuthorizationKey(\\n getOwner(_workerAddress),\\n _workerAddress,\\n _dappAddress\\n )];\\n }\\n\\n function hireAndAuthorize(\\n address payable _workerAddress,\\n address _dappAddress\\n ) public payable {\\n hire(_workerAddress);\\n authorize(_workerAddress, _dappAddress);\\n }\\n}\\n\",\"keccak256\":\"0x3bea45e35de87f18d8c79dffa4b9ccd6106590cace1a7868bf9fbf2a5112d3ff\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610d08806100206000396000f3fe6080604052600436106100e85760003560e01c80639b789b7e1161008a578063d9d6bd8611610059578063d9d6bd8614610272578063dbd9655414610285578063f4dc754b14610298578063fa544161146102b857600080fd5b80639b789b7e146101fd5780639e6371ba14610212578063a00745b614610232578063b64b3bed1461025257600080fd5b806365e4ad9e116100c657806365e4ad9e1461014c5780636d3c62751461016c5780636d892f7e1461018c5780636f77926b146101ac57600080fd5b806303d6e81e146100ed5780632896f60b146100f75780632bef45951461012c575b600080fd5b6100f56102d8565b005b34801561010357600080fd5b50610117610112366004610c4d565b6103f0565b60405190151581526020015b60405180910390f35b34801561013857600080fd5b506100f5610147366004610ca8565b610436565b34801561015857600080fd5b50610117610167366004610ca8565b610575565b34801561017857600080fd5b50610117610187366004610c4d565b6105a9565b34801561019857600080fd5b506100f56101a7366004610ca8565b6105b2565b3480156101b857600080fd5b506101e56101c7366004610c4d565b6001600160a01b039081166000908152602081905260409020541690565b6040516001600160a01b039091168152602001610123565b34801561020957600080fd5b506100f56106e8565b34801561021e57600080fd5b506100f561022d366004610c4d565b6107cd565b34801561023e57600080fd5b5061011761024d366004610c4d565b610901565b34801561025e57600080fd5b506100f561026d366004610c4d565b61090a565b6100f5610280366004610c4d565b610973565b6100f5610293366004610c70565b610b6b565b3480156102a457600080fd5b506101176102b3366004610c4d565b610b82565b3480156102c457600080fd5b506101e56102d3366004610c4d565b610b8b565b336000908152602081905260409020546001600160a01b03166103425760405162461bcd60e51b815260206004820181905260248201527f776f726b657220646f6573206e6f7420686176652061206a6f62206f6666657260448201526064015b60405180910390fd5b3360009081526020818152604080832080546001600160a01b031981169091556001909252808320805460ff19169055516001600160a01b039091169182913480156108fc0292909190818181858888f193505050501580156103a9573d6000803e3d6000fd5b50336000818152602081905260408082205490516001600160a01b0390911692917fac8bfc64efe7b663f325ca81c7468a291a868aacc74c8f91cdc5c8141c15e38a91a350565b6000805b6001600160a01b03831660009081526001602052604090205460ff16600381111561042f57634e487b7160e01b600052602160045260246000fd5b1492915050565b813361045a826001600160a01b039081166000908152602081905260409020541690565b6001600160a01b0316146104b05760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e6465720000000000006044820152606401610339565b60006104bd338585610bf8565b60008181526002602052604090205490915060ff161561051f5760405162461bcd60e51b815260206004820152601760248201527f6461707020616c726561647920617574686f72697a65640000000000000000006044820152606401610339565b600081815260026020526040808220805460ff19166001179055516001600160a01b03808616929087169133917fde756a416a233cdb16c23a1fa5dcb3113164968df8607e0a4eeca25974b96e0391a450505050565b60006002600061058e61058786610b8b565b8686610bf8565b815260208101919091526040016000205460ff169392505050565b600060036103f4565b81336105d6826001600160a01b039081166000908152602081905260409020541690565b6001600160a01b03161461062c5760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e6465720000000000006044820152606401610339565b6000610639338585610bf8565b60008181526002602052604090205490915060ff1615156001146106955760405162461bcd60e51b815260206004820152601360248201527219185c1c081b9bdd08185d5d1a1bdc9a5e9959606a1b6044820152606401610339565b600081815260026020526040808220805460ff19169055516001600160a01b03808616929087169133917f4d2275ddb8a6d9c36c95476c2eaf9746c1785b4ab76a99719fd647b36da46cee91a450505050565b60013360009081526001602052604090205460ff16600381111561071c57634e487b7160e01b600052602160045260246000fd5b146107745760405162461bcd60e51b815260206004820152602260248201527f776f726b6572206e6f74206973206e6f7420696e2070656e64696e6720737461604482015261746560f01b6064820152608401610339565b336000818152600160209081526040808320805460ff19166002179055908290528082205490516001600160a01b0390911692917f0cfa12ab8ee8dc6f9b68938d5e764dafed737d43dc5ec8443abf81e645276eb691a3565b60026001600160a01b03821660009081526001602052604090205460ff16600381111561080a57634e487b7160e01b600052602160045260246000fd5b1461084a5760405162461bcd60e51b815260206004820152601060248201526f1ddbdc9ad95c881b9bdd081bdddb995960821b6044820152606401610339565b6001600160a01b038181166000908152602081905260409020541633146108b35760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2072657469726520776f726b6572000000006044820152606401610339565b6001600160a01b038116600081815260016020526040808220805460ff19166003179055513392917f657b373e1262c26d1f1a83e8949f0af9067fe48026b308e47eec5ef6b40ff25d91a350565b600060016103f4565b6001600160a01b038181166000908152602081905260409020541633146108b35760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792068697265722063616e2063616e63656c20746865206f66666572006044820152606401610339565b61097c816103f0565b6109c85760405162461bcd60e51b815260206004820152601760248201527f776f726b6572206973206e6f7420617661696c61626c650000000000000000006044820152606401610339565b6001600160a01b038116610a1e5760405162461bcd60e51b815260206004820152601d60248201527f776f726b657220616464726573732063616e206e6f74206265203078300000006044820152606401610339565b66038d7ea4c68000341015610a6d5760405162461bcd60e51b815260206004820152601560248201527466756e64696e672062656c6f77206d696e696d756d60581b6044820152606401610339565b6729a2241af62c0000341115610abd5760405162461bcd60e51b815260206004820152601560248201527466756e64696e672061626f7665206d6178696d756d60581b6044820152606401610339565b6001600160a01b03811660009081526020818152604080832080546001600160a01b03191633179055600191829052909120805460ff1916828002179055506040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015610b31573d6000803e3d6000fd5b5060405133906001600160a01b038316907f2e0aa97ef0e6f4f76319861c90e91beec7a7a44a698cab856dfc1985a0c588f090600090a350565b610b7482610973565b610b7e8282610436565b5050565b600060026103f4565b600060026001600160a01b03831660009081526001602052604090205460ff166003811115610bca57634e487b7160e01b600052602160045260246000fd5b14610bd6576000610bf2565b6001600160a01b03808316600090815260208190526040902054165b92915050565b6040516bffffffffffffffffffffffff19606085811b8216602084015284811b8216603484015283901b166048820152600090605c016040516020818303038152906040528051906020012090509392505050565b600060208284031215610c5e578081fd5b8135610c6981610cba565b9392505050565b60008060408385031215610c82578081fd5b8235610c8d81610cba565b91506020830135610c9d81610cba565b809150509250929050565b60008060408385031215610c82578182fd5b6001600160a01b0381168114610ccf57600080fd5b5056fea26469706673582212202700c4e4bbaeb90fae58ff3eb584ca659cec3993a24873987c6c38e6b553627464736f6c63430008040033", + "deployedBytecode": "0x6080604052600436106100e85760003560e01c80639b789b7e1161008a578063d9d6bd8611610059578063d9d6bd8614610272578063dbd9655414610285578063f4dc754b14610298578063fa544161146102b857600080fd5b80639b789b7e146101fd5780639e6371ba14610212578063a00745b614610232578063b64b3bed1461025257600080fd5b806365e4ad9e116100c657806365e4ad9e1461014c5780636d3c62751461016c5780636d892f7e1461018c5780636f77926b146101ac57600080fd5b806303d6e81e146100ed5780632896f60b146100f75780632bef45951461012c575b600080fd5b6100f56102d8565b005b34801561010357600080fd5b50610117610112366004610c4d565b6103f0565b60405190151581526020015b60405180910390f35b34801561013857600080fd5b506100f5610147366004610ca8565b610436565b34801561015857600080fd5b50610117610167366004610ca8565b610575565b34801561017857600080fd5b50610117610187366004610c4d565b6105a9565b34801561019857600080fd5b506100f56101a7366004610ca8565b6105b2565b3480156101b857600080fd5b506101e56101c7366004610c4d565b6001600160a01b039081166000908152602081905260409020541690565b6040516001600160a01b039091168152602001610123565b34801561020957600080fd5b506100f56106e8565b34801561021e57600080fd5b506100f561022d366004610c4d565b6107cd565b34801561023e57600080fd5b5061011761024d366004610c4d565b610901565b34801561025e57600080fd5b506100f561026d366004610c4d565b61090a565b6100f5610280366004610c4d565b610973565b6100f5610293366004610c70565b610b6b565b3480156102a457600080fd5b506101176102b3366004610c4d565b610b82565b3480156102c457600080fd5b506101e56102d3366004610c4d565b610b8b565b336000908152602081905260409020546001600160a01b03166103425760405162461bcd60e51b815260206004820181905260248201527f776f726b657220646f6573206e6f7420686176652061206a6f62206f6666657260448201526064015b60405180910390fd5b3360009081526020818152604080832080546001600160a01b031981169091556001909252808320805460ff19169055516001600160a01b039091169182913480156108fc0292909190818181858888f193505050501580156103a9573d6000803e3d6000fd5b50336000818152602081905260408082205490516001600160a01b0390911692917fac8bfc64efe7b663f325ca81c7468a291a868aacc74c8f91cdc5c8141c15e38a91a350565b6000805b6001600160a01b03831660009081526001602052604090205460ff16600381111561042f57634e487b7160e01b600052602160045260246000fd5b1492915050565b813361045a826001600160a01b039081166000908152602081905260409020541690565b6001600160a01b0316146104b05760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e6465720000000000006044820152606401610339565b60006104bd338585610bf8565b60008181526002602052604090205490915060ff161561051f5760405162461bcd60e51b815260206004820152601760248201527f6461707020616c726561647920617574686f72697a65640000000000000000006044820152606401610339565b600081815260026020526040808220805460ff19166001179055516001600160a01b03808616929087169133917fde756a416a233cdb16c23a1fa5dcb3113164968df8607e0a4eeca25974b96e0391a450505050565b60006002600061058e61058786610b8b565b8686610bf8565b815260208101919091526040016000205460ff169392505050565b600060036103f4565b81336105d6826001600160a01b039081166000908152602081905260409020541690565b6001600160a01b03161461062c5760405162461bcd60e51b815260206004820152601a60248201527f776f726b6572206e6f742068697265642062792073656e6465720000000000006044820152606401610339565b6000610639338585610bf8565b60008181526002602052604090205490915060ff1615156001146106955760405162461bcd60e51b815260206004820152601360248201527219185c1c081b9bdd08185d5d1a1bdc9a5e9959606a1b6044820152606401610339565b600081815260026020526040808220805460ff19169055516001600160a01b03808616929087169133917f4d2275ddb8a6d9c36c95476c2eaf9746c1785b4ab76a99719fd647b36da46cee91a450505050565b60013360009081526001602052604090205460ff16600381111561071c57634e487b7160e01b600052602160045260246000fd5b146107745760405162461bcd60e51b815260206004820152602260248201527f776f726b6572206e6f74206973206e6f7420696e2070656e64696e6720737461604482015261746560f01b6064820152608401610339565b336000818152600160209081526040808320805460ff19166002179055908290528082205490516001600160a01b0390911692917f0cfa12ab8ee8dc6f9b68938d5e764dafed737d43dc5ec8443abf81e645276eb691a3565b60026001600160a01b03821660009081526001602052604090205460ff16600381111561080a57634e487b7160e01b600052602160045260246000fd5b1461084a5760405162461bcd60e51b815260206004820152601060248201526f1ddbdc9ad95c881b9bdd081bdddb995960821b6044820152606401610339565b6001600160a01b038181166000908152602081905260409020541633146108b35760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2072657469726520776f726b6572000000006044820152606401610339565b6001600160a01b038116600081815260016020526040808220805460ff19166003179055513392917f657b373e1262c26d1f1a83e8949f0af9067fe48026b308e47eec5ef6b40ff25d91a350565b600060016103f4565b6001600160a01b038181166000908152602081905260409020541633146108b35760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792068697265722063616e2063616e63656c20746865206f66666572006044820152606401610339565b61097c816103f0565b6109c85760405162461bcd60e51b815260206004820152601760248201527f776f726b6572206973206e6f7420617661696c61626c650000000000000000006044820152606401610339565b6001600160a01b038116610a1e5760405162461bcd60e51b815260206004820152601d60248201527f776f726b657220616464726573732063616e206e6f74206265203078300000006044820152606401610339565b66038d7ea4c68000341015610a6d5760405162461bcd60e51b815260206004820152601560248201527466756e64696e672062656c6f77206d696e696d756d60581b6044820152606401610339565b6729a2241af62c0000341115610abd5760405162461bcd60e51b815260206004820152601560248201527466756e64696e672061626f7665206d6178696d756d60581b6044820152606401610339565b6001600160a01b03811660009081526020818152604080832080546001600160a01b03191633179055600191829052909120805460ff1916828002179055506040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015610b31573d6000803e3d6000fd5b5060405133906001600160a01b038316907f2e0aa97ef0e6f4f76319861c90e91beec7a7a44a698cab856dfc1985a0c588f090600090a350565b610b7482610973565b610b7e8282610436565b5050565b600060026103f4565b600060026001600160a01b03831660009081526001602052604090205460ff166003811115610bca57634e487b7160e01b600052602160045260246000fd5b14610bd6576000610bf2565b6001600160a01b03808316600090815260208190526040902054165b92915050565b6040516bffffffffffffffffffffffff19606085811b8216602084015284811b8216603484015283901b166048820152600090605c016040516020818303038152906040528051906020012090509392505050565b600060208284031215610c5e578081fd5b8135610c6981610cba565b9392505050565b60008060408385031215610c82578081fd5b8235610c8d81610cba565b91506020830135610c9d81610cba565b809150509250929050565b60008060408385031215610c82578182fd5b6001600160a01b0381168114610ccf57600080fd5b5056fea26469706673582212202700c4e4bbaeb90fae58ff3eb584ca659cec3993a24873987c6c38e6b553627464736f6c63430008040033", + "devdoc": { + "kind": "dev", + "methods": { + "authorize(address,address)": { + "params": { + "_dappAddress": "address of the dapp that permission will be given to", + "_workerAddress": "address of the worker node to given permission" + } + }, + "isAuthorized(address,address)": { + "params": { + "_dappAddress": "address of the DApp", + "_workerAddress": "address of the worker" + } + }, + "isAvailable(address)": { + "params": { + "workerAddress": "address of the worker node" + } + }, + "isPending(address)": { + "params": { + "workerAddress": "address of the worker node" + } + } + }, + "stateVariables": { + "MAXIMUM_FUNDING": { + "details": "transfers bigger than maximum value should be done directly" + }, + "MINIMUM_FUNDING": { + "details": "user can only hire a worker if he sends more than minimum value" + }, + "permissions": { + "details": "permissions keyed by hash(user, worker, dapp)" + }, + "stateOf": { + "details": "mapping from worker to its internal state" + }, + "userOf": { + "details": "mapping from worker to its user" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "Authorization(address,address,address)": { + "notice": "A DApp has been authorized by a user for a worker" + }, + "Deauthorization(address,address,address)": { + "notice": "A DApp has been deauthorized by a user for a worker" + }, + "JobOffer(address,address)": { + "notice": "Events signalling every state transition" + } + }, + "kind": "user", + "methods": { + "acceptJob()": { + "notice": "Called by the worker to accept the job" + }, + "authorize(address,address)": { + "notice": "Gives worker permission to act on a DApp" + }, + "isAuthorized(address,address)": { + "notice": "Returns is the dapp is authorized to be called by that worker" + }, + "isAvailable(address)": { + "notice": "Returns true if worker node is available" + }, + "isPending(address)": { + "notice": "Returns true if worker node is pending" + }, + "rejectJob()": { + "notice": "Called by the worker to reject a job offer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 369, + "contract": "contracts/WorkerManagerAuthManagerImpl.sol:WorkerManagerAuthManagerImpl", + "label": "userOf", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_address_payable)" + }, + { + "astId": 375, + "contract": "contracts/WorkerManagerAuthManagerImpl.sol:WorkerManagerAuthManagerImpl", + "label": "stateOf", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_enum(WorkerState)364)" + }, + { + "astId": 380, + "contract": "contracts/WorkerManagerAuthManagerImpl.sol:WorkerManagerAuthManagerImpl", + "label": "permissions", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_bytes32,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_address_payable": { + "encoding": "inplace", + "label": "address payable", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_enum(WorkerState)364": { + "encoding": "inplace", + "label": "enum WorkerManagerAuthManagerImpl.WorkerState", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_address_payable)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address payable)", + "numberOfBytes": "32", + "value": "t_address_payable" + }, + "t_mapping(t_address,t_enum(WorkerState)364)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => enum WorkerManagerAuthManagerImpl.WorkerState)", + "numberOfBytes": "32", + "value": "t_enum(WorkerState)364" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + } + } + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/WorkerManagerImpl.json b/echo-js/deployments/localhost/WorkerManagerImpl.json new file mode 100644 index 00000000..96d277cc --- /dev/null +++ b/echo-js/deployments/localhost/WorkerManagerImpl.json @@ -0,0 +1,373 @@ +{ + "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobOffer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "JobRejected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "worker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "Retired", + "type": "event" + }, + { + "inputs": [], + "name": "acceptJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "cancelHire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "getUser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "hire", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isAvailable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isOwned", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "workerAddress", + "type": "address" + } + ], + "name": "isPending", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "isRetired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rejectJob", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_workerAddress", + "type": "address" + } + ], + "name": "retire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x7a5cf95d0aed9f45b4067319e731a5e7ae16220b11daa8f326b48f6293c857bc", + "receipt": { + "to": null, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "transactionIndex": 0, + "gasUsed": "571031", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xb7471845e401a6e68f62d39f642232c965e711f49ae001787ac622b66a1b9018", + "transactionHash": "0x7a5cf95d0aed9f45b4067319e731a5e7ae16220b11daa8f326b48f6293c857bc", + "logs": [], + "blockNumber": 5, + "cumulativeGasUsed": "571031", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"JobAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"JobOffer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"JobRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"Retired\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"cancelHire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"getUser\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"hire\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workerAddress\",\"type\":\"address\"}],\"name\":\"isAvailable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"isOwned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workerAddress\",\"type\":\"address\"}],\"name\":\"isPending\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"isRetired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rejectJob\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_workerAddress\",\"type\":\"address\"}],\"name\":\"retire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"isAvailable(address)\":{\"params\":{\"workerAddress\":\"address of the worker node\"}},\"isPending(address)\":{\"params\":{\"workerAddress\":\"address of the worker node\"}}},\"stateVariables\":{\"MAXIMUM_FUNDING\":{\"details\":\"transfers bigger than maximum value should be done directly\"},\"MINIMUM_FUNDING\":{\"details\":\"user can only hire a worker if he sends more than minimum value\"},\"stateOf\":{\"details\":\"mapping from worker to its internal state\"},\"userOf\":{\"details\":\"mapping from worker to its user\"}},\"version\":1},\"userdoc\":{\"events\":{\"JobOffer(address,address)\":{\"notice\":\"Events signalling every state transition\"}},\"kind\":\"user\",\"methods\":{\"acceptJob()\":{\"notice\":\"Called by the worker to accept the job\"},\"isAvailable(address)\":{\"notice\":\"Returns true if worker node is available\"},\"isPending(address)\":{\"notice\":\"Returns true if worker node is pending\"},\"rejectJob()\":{\"notice\":\"Called by the worker to reject a job offer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/WorkerManagerImpl.sol\":\"WorkerManagerImpl\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/WorkerManager.sol\":{\"content\":\"// Copyright 2010 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerManager\\n/// @author Danilo Tuler\\npragma solidity >=0.7.0;\\n\\ninterface WorkerManager {\\n /// @notice Returns true if worker node is available\\n /// @param workerAddress address of the worker node\\n function isAvailable(address workerAddress) external view returns (bool);\\n\\n /// @notice Returns true if worker node is pending\\n /// @param workerAddress address of the worker node\\n function isPending(address workerAddress) external view returns (bool);\\n\\n /// @notice Get the owner of the worker node\\n /// @param workerAddress address of the worker node\\n function getOwner(address workerAddress) external view returns (address);\\n\\n /// @notice Get the user of the worker node, which may not be the owner yet, or how was the previous owner of a retired node\\n function getUser(address workerAddress) external view returns (address);\\n\\n /// @notice Returns true if worker node is owned by some user\\n function isOwned(address workerAddress) external view returns (bool);\\n\\n /// @notice Asks the worker to work for the sender. Sender needs to pay something.\\n /// @param workerAddress address of the worker\\n function hire(address payable workerAddress) external payable;\\n\\n /// @notice Called by the worker to accept the job\\n function acceptJob() external;\\n\\n /// @notice Called by the worker to reject a job offer\\n function rejectJob() external payable;\\n\\n /// @notice Called by the user to cancel a job offer\\n /// @param workerAddress address of the worker node\\n function cancelHire(address workerAddress) external;\\n\\n /// @notice Called by the user to retire his worker.\\n /// @param workerAddress address of the worker to be retired\\n /// @dev this also removes all authorizations in place\\n function retire(address payable workerAddress) external;\\n\\n /// @notice Returns true if worker node was retired by its owner\\n function isRetired(address workerAddress) external view returns (bool);\\n\\n /// @notice Events signalling every state transition\\n event JobOffer(address indexed worker, address indexed user);\\n event JobAccepted(address indexed worker, address indexed user);\\n event JobRejected(address indexed worker, address indexed user);\\n event Retired(address indexed worker, address indexed user);\\n}\\n\",\"keccak256\":\"0xb93bac1de98b3fb44421c2498f11bcd246795c7cffeeebb535a046e88c303410\",\"license\":\"Apache-2.0\"},\"contracts/WorkerManagerImpl.sol\":{\"content\":\"// Copyright 2020 Cartesi Pte. Ltd.\\n\\n// SPDX-License-Identifier: Apache-2.0\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\n// this file except in compliance with the License. You may obtain a copy of the\\n// License at http://www.apache.org/licenses/LICENSE-2.0\\n\\n// Unless required by applicable law or agreed to in writing, software distributed\\n// under the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR\\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\\n// specific language governing permissions and limitations under the License.\\n\\n/// @title WorkerManagerImpl\\n/// @author Danilo Tuler\\npragma solidity ^0.8.0;\\n\\nimport \\\"./WorkerManager.sol\\\";\\n\\ncontract WorkerManagerImpl is WorkerManager {\\n /// @dev user can only hire a worker if he sends more than minimum value\\n uint256 constant MINIMUM_FUNDING = 0.001 ether;\\n\\n /// @dev transfers bigger than maximum value should be done directly\\n uint256 constant MAXIMUM_FUNDING = 3 ether;\\n\\n /// @notice A worker can be in 4 different states, starting from Available\\n enum WorkerState {Available, Pending, Owned, Retired}\\n\\n /// @dev mapping from worker to its user\\n mapping(address => address payable) private userOf;\\n\\n /// @dev mapping from worker to its internal state\\n mapping(address => WorkerState) private stateOf;\\n\\n function isAvailable(address workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[workerAddress] == WorkerState.Available;\\n }\\n\\n function isPending(address workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[workerAddress] == WorkerState.Pending;\\n }\\n\\n function getOwner(address _workerAddress)\\n public\\n override\\n view\\n returns (address)\\n {\\n return\\n stateOf[_workerAddress] == WorkerState.Owned\\n ? userOf[_workerAddress]\\n : address(0);\\n }\\n\\n function getUser(address _workerAddress)\\n public\\n override\\n view\\n returns (address)\\n {\\n return userOf[_workerAddress];\\n }\\n\\n function isOwned(address _workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[_workerAddress] == WorkerState.Owned;\\n }\\n\\n function hire(address payable _workerAddress) public override payable {\\n require(isAvailable(_workerAddress), \\\"worker is not available\\\");\\n require(_workerAddress != address(0), \\\"worker address can not be 0x0\\\");\\n require(msg.value >= MINIMUM_FUNDING, \\\"funding below minimum\\\");\\n require(msg.value <= MAXIMUM_FUNDING, \\\"funding above maximum\\\");\\n\\n // set owner\\n userOf[_workerAddress] = payable(msg.sender);\\n\\n // change state\\n stateOf[_workerAddress] = WorkerState.Pending;\\n\\n // transfer ether to worker\\n _workerAddress.transfer(msg.value);\\n\\n // emit event\\n emit JobOffer(_workerAddress, msg.sender);\\n }\\n\\n function acceptJob() public override {\\n require(\\n userOf[msg.sender] != address(0),\\n \\\"worker does not have a job offer\\\"\\n );\\n require(\\n stateOf[msg.sender] == WorkerState.Pending,\\n \\\"worker not is not in pending state\\\"\\n );\\n\\n // change state\\n stateOf[msg.sender] = WorkerState.Owned;\\n // from now on getOwner will return the user\\n\\n // emit event\\n emit JobAccepted(msg.sender, userOf[msg.sender]);\\n }\\n\\n function rejectJob() public override payable {\\n require(\\n userOf[msg.sender] != address(0),\\n \\\"worker does not have a job offer\\\"\\n );\\n\\n address payable owner = userOf[msg.sender];\\n\\n // reset hirer back to null\\n userOf[msg.sender] = payable(address(0));\\n\\n // change state\\n stateOf[msg.sender] = WorkerState.Available;\\n\\n // return the money\\n owner.transfer(msg.value);\\n\\n // emit event\\n emit JobRejected(msg.sender, userOf[msg.sender]);\\n }\\n\\n function cancelHire(address _workerAddress) public override {\\n require(\\n userOf[_workerAddress] != address(0),\\n \\\"worker does not have a job offer\\\"\\n );\\n\\n require(\\n userOf[_workerAddress] == msg.sender,\\n \\\"only hirer can cancel the offer\\\"\\n );\\n\\n // change state\\n stateOf[_workerAddress] = WorkerState.Retired;\\n\\n // emit event\\n emit Retired(_workerAddress, msg.sender);\\n }\\n\\n function retire(address payable _workerAddress) public override {\\n require(\\n stateOf[_workerAddress] == WorkerState.Owned,\\n \\\"worker not owned\\\"\\n );\\n require(\\n userOf[_workerAddress] == msg.sender,\\n \\\"only owner can retire worker\\\"\\n );\\n\\n // change state\\n stateOf[_workerAddress] = WorkerState.Retired;\\n\\n // emit event\\n emit Retired(_workerAddress, msg.sender);\\n }\\n\\n function isRetired(address _workerAddress)\\n public\\n override\\n view\\n returns (bool)\\n {\\n return stateOf[_workerAddress] == WorkerState.Retired;\\n }\\n}\\n\",\"keccak256\":\"0x71a604e959e92f3b30008ac43d25bfc9e73040e2b384e73d1daa607d85bdbd1e\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061095f806100206000396000f3fe60806040526004361061009c5760003560e01c80639e6371ba116100645780639e6371ba14610166578063a00745b614610186578063b64b3bed146101a6578063d9d6bd86146101c6578063f4dc754b146101d9578063fa544161146101f957600080fd5b806303d6e81e146100a15780632896f60b146100ab5780636d3c6275146100e05780636f77926b146101005780639b789b7e14610151575b600080fd5b6100a9610219565b005b3480156100b757600080fd5b506100cb6100c63660046108b9565b610305565b60405190151581526020015b60405180910390f35b3480156100ec57600080fd5b506100cb6100fb3660046108b9565b61034b565b34801561010c57600080fd5b5061013961011b3660046108b9565b6001600160a01b039081166000908152602081905260409020541690565b6040516001600160a01b0390911681526020016100d7565b34801561015d57600080fd5b506100a9610354565b34801561017257600080fd5b506100a96101813660046108b9565b61046e565b34801561019257600080fd5b506100cb6101a13660046108b9565b6105a2565b3480156101b257600080fd5b506100a96101c13660046108b9565b6105ab565b6100a96101d43660046108b9565b61064b565b3480156101e557600080fd5b506100cb6101f43660046108b9565b610843565b34801561020557600080fd5b506101396102143660046108b9565b61084c565b336000908152602081905260409020546001600160a01b03166102575760405162461bcd60e51b815260040161024e906108dc565b60405180910390fd5b3360009081526020818152604080832080546001600160a01b031981169091556001909252808320805460ff19169055516001600160a01b039091169182913480156108fc0292909190818181858888f193505050501580156102be573d6000803e3d6000fd5b50336000818152602081905260408082205490516001600160a01b0390911692917fac8bfc64efe7b663f325ca81c7468a291a868aacc74c8f91cdc5c8141c15e38a91a350565b6000805b6001600160a01b03831660009081526001602052604090205460ff16600381111561034457634e487b7160e01b600052602160045260246000fd5b1492915050565b60006003610309565b336000908152602081905260409020546001600160a01b03166103895760405162461bcd60e51b815260040161024e906108dc565b60013360009081526001602052604090205460ff1660038111156103bd57634e487b7160e01b600052602160045260246000fd5b146104155760405162461bcd60e51b815260206004820152602260248201527f776f726b6572206e6f74206973206e6f7420696e2070656e64696e6720737461604482015261746560f01b606482015260840161024e565b336000818152600160209081526040808320805460ff19166002179055908290528082205490516001600160a01b0390911692917f0cfa12ab8ee8dc6f9b68938d5e764dafed737d43dc5ec8443abf81e645276eb691a3565b60026001600160a01b03821660009081526001602052604090205460ff1660038111156104ab57634e487b7160e01b600052602160045260246000fd5b146104eb5760405162461bcd60e51b815260206004820152601060248201526f1ddbdc9ad95c881b9bdd081bdddb995960821b604482015260640161024e565b6001600160a01b038181166000908152602081905260409020541633146105545760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2072657469726520776f726b657200000000604482015260640161024e565b6001600160a01b038116600081815260016020526040808220805460ff19166003179055513392917f657b373e1262c26d1f1a83e8949f0af9067fe48026b308e47eec5ef6b40ff25d91a350565b60006001610309565b6001600160a01b03818116600090815260208190526040902054166105e25760405162461bcd60e51b815260040161024e906108dc565b6001600160a01b038181166000908152602081905260409020541633146105545760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792068697265722063616e2063616e63656c20746865206f6666657200604482015260640161024e565b61065481610305565b6106a05760405162461bcd60e51b815260206004820152601760248201527f776f726b6572206973206e6f7420617661696c61626c65000000000000000000604482015260640161024e565b6001600160a01b0381166106f65760405162461bcd60e51b815260206004820152601d60248201527f776f726b657220616464726573732063616e206e6f7420626520307830000000604482015260640161024e565b66038d7ea4c680003410156107455760405162461bcd60e51b815260206004820152601560248201527466756e64696e672062656c6f77206d696e696d756d60581b604482015260640161024e565b6729a2241af62c00003411156107955760405162461bcd60e51b815260206004820152601560248201527466756e64696e672061626f7665206d6178696d756d60581b604482015260640161024e565b6001600160a01b03811660009081526020818152604080832080546001600160a01b03191633179055600191829052909120805460ff1916828002179055506040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015610809573d6000803e3d6000fd5b5060405133906001600160a01b038316907f2e0aa97ef0e6f4f76319861c90e91beec7a7a44a698cab856dfc1985a0c588f090600090a350565b60006002610309565b600060026001600160a01b03831660009081526001602052604090205460ff16600381111561088b57634e487b7160e01b600052602160045260246000fd5b146108975760006108b3565b6001600160a01b03808316600090815260208190526040902054165b92915050565b6000602082840312156108ca578081fd5b81356108d581610911565b9392505050565b6020808252818101527f776f726b657220646f6573206e6f7420686176652061206a6f62206f66666572604082015260600190565b6001600160a01b038116811461092657600080fd5b5056fea26469706673582212204f10e5c420944ca621a08a09fa16ebe0123c0a671181c14a268338dad73fcebc64736f6c63430008040033", + "deployedBytecode": "0x60806040526004361061009c5760003560e01c80639e6371ba116100645780639e6371ba14610166578063a00745b614610186578063b64b3bed146101a6578063d9d6bd86146101c6578063f4dc754b146101d9578063fa544161146101f957600080fd5b806303d6e81e146100a15780632896f60b146100ab5780636d3c6275146100e05780636f77926b146101005780639b789b7e14610151575b600080fd5b6100a9610219565b005b3480156100b757600080fd5b506100cb6100c63660046108b9565b610305565b60405190151581526020015b60405180910390f35b3480156100ec57600080fd5b506100cb6100fb3660046108b9565b61034b565b34801561010c57600080fd5b5061013961011b3660046108b9565b6001600160a01b039081166000908152602081905260409020541690565b6040516001600160a01b0390911681526020016100d7565b34801561015d57600080fd5b506100a9610354565b34801561017257600080fd5b506100a96101813660046108b9565b61046e565b34801561019257600080fd5b506100cb6101a13660046108b9565b6105a2565b3480156101b257600080fd5b506100a96101c13660046108b9565b6105ab565b6100a96101d43660046108b9565b61064b565b3480156101e557600080fd5b506100cb6101f43660046108b9565b610843565b34801561020557600080fd5b506101396102143660046108b9565b61084c565b336000908152602081905260409020546001600160a01b03166102575760405162461bcd60e51b815260040161024e906108dc565b60405180910390fd5b3360009081526020818152604080832080546001600160a01b031981169091556001909252808320805460ff19169055516001600160a01b039091169182913480156108fc0292909190818181858888f193505050501580156102be573d6000803e3d6000fd5b50336000818152602081905260408082205490516001600160a01b0390911692917fac8bfc64efe7b663f325ca81c7468a291a868aacc74c8f91cdc5c8141c15e38a91a350565b6000805b6001600160a01b03831660009081526001602052604090205460ff16600381111561034457634e487b7160e01b600052602160045260246000fd5b1492915050565b60006003610309565b336000908152602081905260409020546001600160a01b03166103895760405162461bcd60e51b815260040161024e906108dc565b60013360009081526001602052604090205460ff1660038111156103bd57634e487b7160e01b600052602160045260246000fd5b146104155760405162461bcd60e51b815260206004820152602260248201527f776f726b6572206e6f74206973206e6f7420696e2070656e64696e6720737461604482015261746560f01b606482015260840161024e565b336000818152600160209081526040808320805460ff19166002179055908290528082205490516001600160a01b0390911692917f0cfa12ab8ee8dc6f9b68938d5e764dafed737d43dc5ec8443abf81e645276eb691a3565b60026001600160a01b03821660009081526001602052604090205460ff1660038111156104ab57634e487b7160e01b600052602160045260246000fd5b146104eb5760405162461bcd60e51b815260206004820152601060248201526f1ddbdc9ad95c881b9bdd081bdddb995960821b604482015260640161024e565b6001600160a01b038181166000908152602081905260409020541633146105545760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2072657469726520776f726b657200000000604482015260640161024e565b6001600160a01b038116600081815260016020526040808220805460ff19166003179055513392917f657b373e1262c26d1f1a83e8949f0af9067fe48026b308e47eec5ef6b40ff25d91a350565b60006001610309565b6001600160a01b03818116600090815260208190526040902054166105e25760405162461bcd60e51b815260040161024e906108dc565b6001600160a01b038181166000908152602081905260409020541633146105545760405162461bcd60e51b815260206004820152601f60248201527f6f6e6c792068697265722063616e2063616e63656c20746865206f6666657200604482015260640161024e565b61065481610305565b6106a05760405162461bcd60e51b815260206004820152601760248201527f776f726b6572206973206e6f7420617661696c61626c65000000000000000000604482015260640161024e565b6001600160a01b0381166106f65760405162461bcd60e51b815260206004820152601d60248201527f776f726b657220616464726573732063616e206e6f7420626520307830000000604482015260640161024e565b66038d7ea4c680003410156107455760405162461bcd60e51b815260206004820152601560248201527466756e64696e672062656c6f77206d696e696d756d60581b604482015260640161024e565b6729a2241af62c00003411156107955760405162461bcd60e51b815260206004820152601560248201527466756e64696e672061626f7665206d6178696d756d60581b604482015260640161024e565b6001600160a01b03811660009081526020818152604080832080546001600160a01b03191633179055600191829052909120805460ff1916828002179055506040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015610809573d6000803e3d6000fd5b5060405133906001600160a01b038316907f2e0aa97ef0e6f4f76319861c90e91beec7a7a44a698cab856dfc1985a0c588f090600090a350565b60006002610309565b600060026001600160a01b03831660009081526001602052604090205460ff16600381111561088b57634e487b7160e01b600052602160045260246000fd5b146108975760006108b3565b6001600160a01b03808316600090815260208190526040902054165b92915050565b6000602082840312156108ca578081fd5b81356108d581610911565b9392505050565b6020808252818101527f776f726b657220646f6573206e6f7420686176652061206a6f62206f66666572604082015260600190565b6001600160a01b038116811461092657600080fd5b5056fea26469706673582212204f10e5c420944ca621a08a09fa16ebe0123c0a671181c14a268338dad73fcebc64736f6c63430008040033", + "devdoc": { + "kind": "dev", + "methods": { + "isAvailable(address)": { + "params": { + "workerAddress": "address of the worker node" + } + }, + "isPending(address)": { + "params": { + "workerAddress": "address of the worker node" + } + } + }, + "stateVariables": { + "MAXIMUM_FUNDING": { + "details": "transfers bigger than maximum value should be done directly" + }, + "MINIMUM_FUNDING": { + "details": "user can only hire a worker if he sends more than minimum value" + }, + "stateOf": { + "details": "mapping from worker to its internal state" + }, + "userOf": { + "details": "mapping from worker to its user" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "JobOffer(address,address)": { + "notice": "Events signalling every state transition" + } + }, + "kind": "user", + "methods": { + "acceptJob()": { + "notice": "Called by the worker to accept the job" + }, + "isAvailable(address)": { + "notice": "Returns true if worker node is available" + }, + "isPending(address)": { + "notice": "Returns true if worker node is pending" + }, + "rejectJob()": { + "notice": "Called by the worker to reject a job offer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 903, + "contract": "contracts/WorkerManagerImpl.sol:WorkerManagerImpl", + "label": "userOf", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_address_payable)" + }, + { + "astId": 909, + "contract": "contracts/WorkerManagerImpl.sol:WorkerManagerImpl", + "label": "stateOf", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_enum(WorkerState)898)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_address_payable": { + "encoding": "inplace", + "label": "address payable", + "numberOfBytes": "20" + }, + "t_enum(WorkerState)898": { + "encoding": "inplace", + "label": "enum WorkerManagerImpl.WorkerState", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_address_payable)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address payable)", + "numberOfBytes": "32", + "value": "t_address_payable" + }, + "t_mapping(t_address,t_enum(WorkerState)898)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => enum WorkerManagerImpl.WorkerState)", + "numberOfBytes": "32", + "value": "t_enum(WorkerState)898" + } + } + } +} \ No newline at end of file diff --git a/echo-js/deployments/localhost/dapp.address b/echo-js/deployments/localhost/dapp.address new file mode 100644 index 00000000..6e8c0685 --- /dev/null +++ b/echo-js/deployments/localhost/dapp.address @@ -0,0 +1 @@ +0xa37aE2b259D35aF4aBdde122eC90B204323ED304 \ No newline at end of file diff --git a/echo-js/deployments/localhost/solcInputs/853463bf44733f3d929a32fa4eacb9e6.json b/echo-js/deployments/localhost/solcInputs/853463bf44733f3d929a32fa4eacb9e6.json new file mode 100644 index 00000000..735c1e6d --- /dev/null +++ b/echo-js/deployments/localhost/solcInputs/853463bf44733f3d929a32fa4eacb9e6.json @@ -0,0 +1,203 @@ +{ + "language": "Solidity", + "sources": { + "contracts/Bank.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n// @title Bank contract\npragma solidity ^0.8.0;\n\nimport {IBank} from \"./IBank.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract Bank is IBank {\n IERC20 private immutable token;\n\n // `balances` maps account/contract addresses to balances\n mapping(address => uint256) private balances;\n\n constructor(address _token) {\n require(_token != address(0), \"Bank: invalid token\");\n token = IERC20(_token);\n }\n\n function getToken() public view override returns (IERC20) {\n return token;\n }\n\n function balanceOf(address _owner) public view override returns (uint256) {\n return balances[_owner];\n }\n\n function transferTokens(address _to, uint256 _value) public override {\n // checks\n uint256 balance = balances[msg.sender];\n require(_value <= balance, \"Bank: not enough balance\");\n\n // effects\n // Note: this should not underflow because we checked that\n // `_value <= balance` in the `require` above\n unchecked {\n balances[msg.sender] = balance - _value;\n }\n\n // interactions\n // Note: a well-implemented ERC-20 contract should already\n // require the recipient (in this case, `_to`) to be different\n // than address(0), so we don't need to check it ourselves\n require(token.transfer(_to, _value), \"Bank: transfer failed\");\n emit Transfer(msg.sender, _to, _value);\n }\n\n function depositTokens(address _to, uint256 _value) public override {\n // checks\n require(_to != address(0), \"Bank: invalid recipient\");\n\n // effects\n // Note: this should not overflow because `IERC20.totalSupply`\n // returns a `uint256` value, so there can't be more than\n // `uint256.max` tokens in an ERC-20 contract.\n balances[_to] += _value;\n\n // interactions\n // Note: transfers tokens to bank, but emits `Deposit` event\n // with recipient being `_to`\n require(\n token.transferFrom(msg.sender, address(this), _value),\n \"Bank: transferFrom failed\"\n );\n emit Deposit(msg.sender, _to, _value);\n }\n}\n" + }, + "contracts/IBank.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n// @title Bank interface\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IBank {\n /// @notice returns the token used internally\n function getToken() external view returns (IERC20);\n\n /// @notice get balance of `_owner`\n /// @param _owner account owner\n function balanceOf(address _owner) external view returns (uint256);\n\n /// @notice transfer `_value` tokens from bank to `_to`\n /// @notice decrease the balance of caller by `_value`\n /// @param _to account that will receive `_value` tokens\n /// @param _value amount of tokens to be transfered\n function transferTokens(address _to, uint256 _value) external;\n\n /// @notice transfer `_value` tokens from caller to bank\n /// @notice increase the balance of `_to` by `_value`\n /// @dev you may need to call `token.approve(bank, _value)`\n /// @param _to account that will have their balance increased by `_value`\n /// @param _value amount of tokens to be transfered\n function depositTokens(address _to, uint256 _value) external;\n\n /// @notice `value` tokens were transfered from the bank to `to`\n /// @notice the balance of `from` was decreased by `value`\n /// @dev is triggered on any successful call to `transferTokens`\n /// @param from the account/contract that called `transferTokens` and\n /// got their balance decreased by `value`\n /// @param to the one that received `value` tokens from the bank\n /// @param value amount of tokens that were transfered\n event Transfer(address indexed from, address to, uint256 value);\n\n /// @notice `value` tokens were transfered from `from` to bank\n /// @notice the balance of `to` was increased by `value`\n /// @dev is triggered on any successful call to `depositTokens`\n /// @param from the account/contract that called `depositTokens` and\n /// transfered `value` tokens to the bank\n /// @param to the one that got their balance increased by `value`\n /// @param value amount of tokens that were transfered\n event Deposit(address from, address indexed to, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: owner query for nonexistent token\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory _data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, _data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits a {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits a {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/facets/ERC721PortalFacet.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Generic ERC721 Portal facet\npragma solidity ^0.8.0;\n\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\nimport {IERC721Portal} from \"../interfaces/IERC721Portal.sol\";\n\nimport {LibInput} from \"../libraries/LibInput.sol\";\n\ncontract ERC721PortalFacet is IERC721Portal {\n using LibInput for LibInput.DiamondStorage;\n\n bytes32 constant INPUT_HEADER = keccak256(\"ERC721_Transfer\");\n\n /// @notice Handle the receipt of an NFT\n /// @dev The ERC721 smart contract calls this function on the recipient\n /// after a `transfer`. This function MAY throw to revert and reject the\n /// transfer. Return of other than the magic value MUST result in the\n /// transaction being reverted.\n /// Note: the contract address is always the message sender.\n /// @param _operator The address which called `safeTransferFrom` function\n /// @param _from The address which previously owned the token\n /// @param _tokenId The NFT identifier which is being transferred\n /// @param _data Additional data to be interpreted by L2\n /// @return this function selector unless throwing\n function onERC721Received(\n address _operator,\n address _from,\n uint256 _tokenId,\n bytes calldata _data\n ) public override returns (bytes4) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n address erc721Contract = msg.sender;\n\n bytes memory input = abi.encode(\n INPUT_HEADER,\n erc721Contract,\n _operator,\n _from,\n _tokenId,\n _data\n );\n\n inputDS.addInternalInput(input);\n\n emit ERC721Received(erc721Contract, _operator, _from, _tokenId, _data);\n\n // return the magic value to approve the transfer\n return this.onERC721Received.selector;\n }\n\n /// @notice withdraw an ERC721 token from the portal\n /// @param _data data with withdrawal information\n /// @dev can only be called by the Rollups contract\n function erc721Withdrawal(bytes calldata _data)\n public\n override\n returns (bool)\n {\n // Delegate calls preserve msg.sender, msg.value and address(this)\n require(msg.sender == address(this), \"only itself\");\n\n (address tokenAddr, address payable receiver, uint256 tokenId) = abi\n .decode(_data, (address, address, uint256));\n\n IERC721 token = IERC721(tokenAddr);\n\n // transfer reverts on failure\n token.safeTransferFrom(address(this), receiver, tokenId);\n\n emit ERC721Withdrawn(tokenAddr, receiver, tokenId);\n return true;\n }\n}\n" + }, + "contracts/interfaces/IERC721Portal.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Generic ERC721 Portal interface\npragma solidity >=0.7.0;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\n\ninterface IERC721Portal is IERC721Receiver {\n /// @notice withdraw an ERC721 token from the portal\n /// @param _data data with withdrawal information\n /// @dev can only be called by the Rollups contract\n function erc721Withdrawal(bytes calldata _data) external returns (bool);\n\n /// @notice emitted on a call to `onERC721Received`\n event ERC721Received(\n address ERC721,\n address operator,\n address sender,\n uint256 tokenId,\n bytes data\n );\n\n /// @notice emitted on ERC721 withdrawal\n event ERC721Withdrawn(\n address ERC721,\n address payable receiver,\n uint256 tokenId\n );\n}\n" + }, + "contracts/libraries/LibInput.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Input library\npragma solidity ^0.8.0;\n\nimport {LibRollups} from \"../libraries/LibRollups.sol\";\n\nlibrary LibInput {\n using LibRollups for LibRollups.DiamondStorage;\n\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"Input.diamond.storage\");\n\n struct DiamondStorage {\n // always needs to keep track of two input boxes:\n // 1 for the input accumulation of next epoch\n // and 1 for the messages during current epoch. To save gas we alternate\n // between inputBox0 and inputBox1\n bytes32[] inputBox0;\n bytes32[] inputBox1;\n uint256 inputDriveSize; // size of input flashdrive\n uint256 currentInputBox;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n /// @notice get input inside inbox of currently proposed claim\n /// @param ds diamond storage pointer\n /// @param index index of input inside that inbox\n /// @return hash of input at index index\n /// @dev currentInputBox being zero means that the inputs for\n /// the claimed epoch are on input box one\n function getInput(DiamondStorage storage ds, uint256 index)\n internal\n view\n returns (bytes32)\n {\n return\n ds.currentInputBox == 0 ? ds.inputBox1[index] : ds.inputBox0[index];\n }\n\n /// @notice get number of inputs inside inbox of currently proposed claim\n /// @param ds diamond storage pointer\n /// @return number of inputs on that input box\n /// @dev currentInputBox being zero means that the inputs for\n /// the claimed epoch are on input box one\n function getNumberOfInputs(DiamondStorage storage ds)\n internal\n view\n returns (uint256)\n {\n return\n ds.currentInputBox == 0 ? ds.inputBox1.length : ds.inputBox0.length;\n }\n\n /// @notice add input to processed by next epoch\n /// @param ds diamond storage pointer\n /// @param input input to be understood by offchain machine\n /// @dev offchain code is responsible for making sure\n /// that input size is power of 2 and multiple of 8 since\n /// the offchain machine has a 8 byte word\n function addInput(DiamondStorage storage ds, bytes memory input)\n internal\n returns (bytes32)\n {\n return addInputFromSender(ds, input, msg.sender);\n }\n\n /// @notice add internal input to processed by next epoch\n /// @notice this function is to be reserved for internal usage only\n /// @notice for normal inputs, call `addInput` instead\n /// @param ds diamond storage pointer\n /// @param input input to be understood by offchain machine\n /// @dev offchain code is responsible for making sure\n /// that input size is power of 2 and multiple of 8 since\n /// the offchain machine has a 8 byte word\n function addInternalInput(DiamondStorage storage ds, bytes memory input)\n internal\n returns (bytes32)\n {\n return addInputFromSender(ds, input, address(this));\n }\n\n /// @notice add input from a specific sender to processed by next epoch\n /// @notice this function is to be reserved for internal usage only\n /// @notice for normal inputs, call `addInput` instead\n /// @param ds diamond storage pointer\n /// @param input input to be understood by offchain machine\n /// @param sender input sender address\n /// @dev offchain code is responsible for making sure\n /// that input size is power of 2 and multiple of 8 since\n /// the offchain machine has a 8 byte word\n function addInputFromSender(\n DiamondStorage storage ds,\n bytes memory input,\n address sender\n ) internal returns (bytes32) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n\n require(input.length <= ds.inputDriveSize, \"input len: [0,driveSize]\");\n\n // notifyInput returns true if that input\n // belongs to a new epoch\n if (rollupsDS.notifyInput()) {\n swapInputBox(ds);\n }\n\n // points to correct inputBox\n bytes32[] storage inputBox = ds.currentInputBox == 0\n ? ds.inputBox0\n : ds.inputBox1;\n\n // get current epoch index\n uint256 currentEpoch = rollupsDS.getCurrentEpoch();\n\n // keccak 64 bytes into 32 bytes\n bytes32 keccakMetadata = keccak256(\n abi.encode(\n sender,\n block.number,\n block.timestamp,\n currentEpoch, // epoch index\n inputBox.length // input index\n )\n );\n\n bytes32 keccakInput = keccak256(input);\n\n bytes32 inputHash = keccak256(abi.encode(keccakMetadata, keccakInput));\n\n // add input to correct inbox\n inputBox.push(inputHash);\n\n emit InputAdded(\n currentEpoch,\n inputBox.length - 1,\n sender,\n block.timestamp,\n input\n );\n\n return inputHash;\n }\n\n /// @notice called when a new input accumulation phase begins\n /// swap inbox to receive inputs for upcoming epoch\n /// @param ds diamond storage pointer\n function onNewInputAccumulation(DiamondStorage storage ds) internal {\n swapInputBox(ds);\n }\n\n /// @notice called when a new epoch begins, clears deprecated inputs\n /// @param ds diamond storage pointer\n function onNewEpoch(DiamondStorage storage ds) internal {\n // clear input box for new inputs\n // the current input box should be accumulating inputs\n // for the new epoch already. So we clear the other one.\n ds.currentInputBox == 0 ? delete ds.inputBox1 : delete ds.inputBox0;\n }\n\n /// @notice changes current input box\n /// @param ds diamond storage pointer\n function swapInputBox(DiamondStorage storage ds) internal {\n ds.currentInputBox = (ds.currentInputBox == 0) ? 1 : 0;\n }\n\n /// @notice input added\n /// @param epochNumber which epoch this input belongs to\n /// @param inputIndex index of the input just added\n /// @param sender msg.sender\n /// @param timestamp block.timestamp\n /// @param input input data\n event InputAdded(\n uint256 indexed epochNumber,\n uint256 indexed inputIndex,\n address sender,\n uint256 timestamp,\n bytes input\n );\n}\n" + }, + "contracts/libraries/LibRollups.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Rollups library\npragma solidity ^0.8.0;\n\nimport {Phase} from \"../interfaces/IRollups.sol\";\nimport {Result} from \"../interfaces/IValidatorManager.sol\";\n\nimport {LibInput} from \"../libraries/LibInput.sol\";\nimport {LibOutput} from \"../libraries/LibOutput.sol\";\nimport {LibValidatorManager} from \"../libraries/LibValidatorManager.sol\";\nimport {LibDisputeManager} from \"../libraries/LibDisputeManager.sol\";\n\nlibrary LibRollups {\n using LibInput for LibInput.DiamondStorage;\n using LibOutput for LibOutput.DiamondStorage;\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\n\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"Rollups.diamond.storage\");\n\n struct DiamondStorage {\n bytes32 templateHash; // state hash of the cartesi machine at t0\n uint32 inputDuration; // duration of input accumulation phase in seconds\n uint32 challengePeriod; // duration of challenge period in seconds\n uint32 inputAccumulationStart; // timestamp when current input accumulation phase started\n uint32 sealingEpochTimestamp; // timestamp on when a proposed epoch (claim) becomes challengeable\n uint32 currentPhase_int; // current phase in integer form\n }\n\n /// @notice epoch finalized\n /// @param epochNumber number of the epoch being finalized\n /// @param epochHash claim being submitted by this epoch\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\n\n /// @notice dispute resolved\n /// @param winner winner of dispute\n /// @param loser loser of dispute\n /// @param winningClaim initial claim of winning validator\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\n\n /// @notice phase change\n /// @param newPhase new phase\n event PhaseChange(Phase newPhase);\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n /// @notice called when new input arrives, manages the phase changes\n /// @param ds diamond storage pointer\n /// @dev can only be called by input contract\n function notifyInput(DiamondStorage storage ds) internal returns (bool) {\n Phase currentPhase = Phase(ds.currentPhase_int);\n uint256 inputAccumulationStart = ds.inputAccumulationStart;\n uint256 inputDuration = ds.inputDuration;\n\n if (\n currentPhase == Phase.InputAccumulation &&\n block.timestamp > inputAccumulationStart + inputDuration\n ) {\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\n emit PhaseChange(Phase.AwaitingConsensus);\n return true;\n }\n return false;\n }\n\n /// @notice called when a dispute is resolved by the dispute manager\n /// @param ds diamond storage pointer\n /// @param winner winner of dispute\n /// @param loser loser of dispute\n /// @param winningClaim initial claim of winning validator\n function resolveDispute(\n DiamondStorage storage ds,\n address payable winner,\n address payable loser,\n bytes32 winningClaim\n ) internal {\n Result result;\n bytes32[2] memory claims;\n address payable[2] memory claimers;\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n\n (result, claims, claimers) = validatorManagerDS.onDisputeEnd(\n winner,\n loser,\n winningClaim\n );\n\n // restart challenge period\n ds.sealingEpochTimestamp = uint32(block.timestamp);\n\n emit ResolveDispute(winner, loser, winningClaim);\n resolveValidatorResult(ds, result, claims, claimers);\n }\n\n /// @notice resolve results returned by validator manager\n /// @param ds diamond storage pointer\n /// @param result result from claim or dispute operation\n /// @param claims array of claims in case of new conflict\n /// @param claimers array of claimers in case of new conflict\n function resolveValidatorResult(\n DiamondStorage storage ds,\n Result result,\n bytes32[2] memory claims,\n address payable[2] memory claimers\n ) internal {\n if (result == Result.NoConflict) {\n Phase currentPhase = Phase(ds.currentPhase_int);\n if (currentPhase != Phase.AwaitingConsensus) {\n ds.currentPhase_int = uint32(Phase.AwaitingConsensus);\n emit PhaseChange(Phase.AwaitingConsensus);\n }\n } else if (result == Result.Consensus) {\n startNewEpoch(ds);\n } else {\n // for the case when result == Result.Conflict\n Phase currentPhase = Phase(ds.currentPhase_int);\n if (currentPhase != Phase.AwaitingDispute) {\n ds.currentPhase_int = uint32(Phase.AwaitingDispute);\n emit PhaseChange(Phase.AwaitingDispute);\n }\n LibDisputeManager.initiateDispute(claims, claimers);\n }\n }\n\n /// @notice starts new epoch\n /// @param ds diamond storage pointer\n function startNewEpoch(DiamondStorage storage ds) internal {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n\n // reset input accumulation start and deactivate challenge period start\n ds.currentPhase_int = uint32(Phase.InputAccumulation);\n emit PhaseChange(Phase.InputAccumulation);\n ds.inputAccumulationStart = uint32(block.timestamp);\n ds.sealingEpochTimestamp = type(uint32).max;\n\n bytes32 finalClaim = validatorManagerDS.onNewEpoch();\n\n // emit event before finalized epoch is added to the Output storage\n emit FinalizeEpoch(outputDS.getNumberOfFinalizedEpochs(), finalClaim);\n\n outputDS.onNewEpoch(finalClaim);\n inputDS.onNewEpoch();\n }\n\n /// @notice returns index of current (accumulating) epoch\n /// @param ds diamond storage pointer\n /// @return index of current epoch\n /// @dev if phase is input accumulation, then the epoch number is length\n /// of finalized epochs array, else there are two non finalized epochs,\n /// one awaiting consensus/dispute and another accumulating input\n function getCurrentEpoch(DiamondStorage storage ds)\n internal\n view\n returns (uint256)\n {\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n\n uint256 finalizedEpochs = outputDS.getNumberOfFinalizedEpochs();\n\n Phase currentPhase = Phase(ds.currentPhase_int);\n\n return\n currentPhase == Phase.InputAccumulation\n ? finalizedEpochs\n : finalizedEpochs + 1;\n }\n}\n" + }, + "contracts/interfaces/IRollups.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Rollups interface\npragma solidity >=0.7.0;\n\n// InputAccumulation - Inputs being accumulated for currrent epoch\n// AwaitingConsensus - No disagreeing claims (or no claims)\n// AwaitingDispute - Waiting for dispute to be over\n// inputs received during InputAccumulation will be included in the\n// current epoch. Inputs received while WaitingClaims or ChallengesInProgress\n// are accumulated for the next epoch\nenum Phase {\n InputAccumulation,\n AwaitingConsensus,\n AwaitingDispute\n}\n\ninterface IRollups {\n /// @notice claim the result of current epoch\n /// @param _epochHash hash of epoch\n /// @dev ValidatorManager makes sure that msg.sender is allowed\n /// and that claim != bytes32(0)\n /// TODO: add signatures for aggregated claims\n function claim(bytes32 _epochHash) external;\n\n /// @notice finalize epoch after timeout\n /// @dev can only be called if challenge period is over\n function finalizeEpoch() external;\n\n /// @notice returns index of current (accumulating) epoch\n /// @return index of current epoch\n /// @dev if phase is input accumulation, then the epoch number is length\n /// of finalized epochs array, else there are two epochs two non\n /// finalized epochs, one awaiting consensus/dispute and another\n /// accumulating input\n function getCurrentEpoch() external view returns (uint256);\n\n /// @notice claim submitted\n /// @param epochHash claim being submitted by this epoch\n /// @param claimer address of current claimer\n /// @param epochNumber number of the epoch being submitted\n event Claim(\n uint256 indexed epochNumber,\n address claimer,\n bytes32 epochHash\n );\n\n /// @notice epoch finalized\n /// @param epochNumber number of the epoch being finalized\n /// @param epochHash claim being submitted by this epoch\n event FinalizeEpoch(uint256 indexed epochNumber, bytes32 epochHash);\n\n /// @notice dispute resolved\n /// @param winner winner of dispute\n /// @param loser loser of dispute\n /// @param winningClaim initial claim of winning validator\n event ResolveDispute(address winner, address loser, bytes32 winningClaim);\n\n /// @notice phase change\n /// @param newPhase new phase\n event PhaseChange(Phase newPhase);\n}\n" + }, + "contracts/interfaces/IValidatorManager.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Validator Manager interface\npragma solidity >=0.7.0;\n\n// NoConflict - No conflicting claims or consensus\n// Consensus - All validators had equal claims\n// Conflict - Claim is conflicting with previous one\nenum Result {\n NoConflict,\n Consensus,\n Conflict\n}\n\n// TODO: What is the incentive for validators to not just copy the first claim that arrived?\ninterface IValidatorManager {\n /// @notice get current claim\n function getCurrentClaim() external view returns (bytes32);\n\n /// @notice emitted on Claim received\n event ClaimReceived(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on Dispute end\n event DisputeEnded(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on new Epoch\n event NewEpoch(bytes32 claim);\n}\n" + }, + "contracts/libraries/LibOutput.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Output library\npragma solidity ^0.8.0;\n\nlibrary LibOutput {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"Output.diamond.storage\");\n\n struct DiamondStorage {\n mapping(uint256 => uint256) voucherBitmask;\n bytes32[] epochHashes;\n bool lock; //reentrancy lock\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n /// @notice to be called when an epoch is finalized\n /// @param ds diamond storage pointer\n /// @param epochHash hash of finalized epoch\n /// @dev an epoch being finalized means that its vouchers can be called\n function onNewEpoch(DiamondStorage storage ds, bytes32 epochHash) internal {\n ds.epochHashes.push(epochHash);\n }\n\n /// @notice get number of finalized epochs\n /// @param ds diamond storage pointer\n function getNumberOfFinalizedEpochs(DiamondStorage storage ds)\n internal\n view\n returns (uint256)\n {\n return ds.epochHashes.length;\n }\n}\n" + }, + "contracts/libraries/LibValidatorManager.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Validator Manager library\npragma solidity ^0.8.0;\n\nimport {Result} from \"../interfaces/IValidatorManager.sol\";\n\nimport {LibClaimsMask, ClaimsMask} from \"../libraries/LibClaimsMask.sol\";\nimport {LibFeeManager} from \"../libraries/LibFeeManager.sol\";\n\nlibrary LibValidatorManager {\n using LibClaimsMask for ClaimsMask;\n using LibFeeManager for LibFeeManager.DiamondStorage;\n\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ValidatorManager.diamond.storage\");\n\n struct DiamondStorage {\n bytes32 currentClaim; // current claim - first claim of this epoch\n address payable[] validators; // up to 8 validators\n uint256 maxNumValidators; // the maximum number of validators, set in the constructor\n // A bit set used for up to 8 validators.\n // The first 8 bits are used to indicate whom supports the current claim\n // The second 8 bits are used to indicate those should have claimed in order to reach consensus\n // The following every 30 bits are used to indicate the number of total claims each validator has made\n // | agreement mask | consensus mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\n // | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\n ClaimsMask claimsMask;\n }\n\n /// @notice emitted on Claim received\n event ClaimReceived(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on Dispute end\n event DisputeEnded(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on new Epoch\n event NewEpoch(bytes32 claim);\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n /// @notice called when a dispute ends in rollups\n /// @param ds diamond storage pointer\n /// @param winner address of dispute winner\n /// @param loser address of dispute loser\n /// @param winningClaim the winnning claim\n /// @return result of dispute being finished\n function onDisputeEnd(\n DiamondStorage storage ds,\n address payable winner,\n address payable loser,\n bytes32 winningClaim\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n removeValidator(ds, loser);\n\n if (winningClaim == ds.currentClaim) {\n // first claim stood, dont need to update the bitmask\n return\n isConsensus(ds)\n ? emitDisputeEndedAndReturn(\n Result.Consensus,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n )\n : emitDisputeEndedAndReturn(\n Result.NoConflict,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n );\n }\n\n // if first claim lost, and other validators have agreed with it\n // there is a new dispute to be played\n if (ds.claimsMask.getAgreementMask() != 0) {\n return\n emitDisputeEndedAndReturn(\n Result.Conflict,\n [ds.currentClaim, winningClaim],\n [getClaimerOfCurrentClaim(ds), winner]\n );\n }\n // else there are no valdiators that agree with losing claim\n // we can update current claim and check for consensus in case\n // the winner is the only validator left\n ds.currentClaim = winningClaim;\n updateClaimAgreementMask(ds, winner);\n return\n isConsensus(ds)\n ? emitDisputeEndedAndReturn(\n Result.Consensus,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n )\n : emitDisputeEndedAndReturn(\n Result.NoConflict,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n );\n }\n\n /// @notice called when a new epoch starts\n /// @param ds diamond storage pointer\n /// @return current claim\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\n // reward validators who has made the correct claim by increasing their #claims\n claimFinalizedIncreaseCounts(ds);\n\n bytes32 tmpClaim = ds.currentClaim;\n\n // clear current claim\n ds.currentClaim = bytes32(0);\n // clear validator agreement bit mask\n ds.claimsMask = ds.claimsMask.clearAgreementMask();\n\n emit NewEpoch(tmpClaim);\n return tmpClaim;\n }\n\n /// @notice called when a claim is received by rollups\n /// @param ds diamond storage pointer\n /// @param sender address of sender of that claim\n /// @param claim claim received by rollups\n /// @return result of claim, Consensus | NoConflict | Conflict\n /// @return [currentClaim, conflicting claim] if there is Conflict\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\n /// @return [claimer1, claimer2] if there is Conflcit\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\n function onClaim(\n DiamondStorage storage ds,\n address payable sender,\n bytes32 claim\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n require(claim != bytes32(0), \"empty claim\");\n require(isValidator(ds, sender), \"sender not allowed\");\n\n // require the validator hasn't claimed in the same epoch before\n uint256 index = getValidatorIndex(ds, sender);\n require(\n !ds.claimsMask.alreadyClaimed(index),\n \"sender had claimed in this epoch before\"\n );\n\n // cant return because a single claim might mean consensus\n if (ds.currentClaim == bytes32(0)) {\n ds.currentClaim = claim;\n } else if (claim != ds.currentClaim) {\n return\n emitClaimReceivedAndReturn(\n Result.Conflict,\n [ds.currentClaim, claim],\n [getClaimerOfCurrentClaim(ds), sender]\n );\n }\n updateClaimAgreementMask(ds, sender);\n\n return\n isConsensus(ds)\n ? emitClaimReceivedAndReturn(\n Result.Consensus,\n [claim, bytes32(0)],\n [sender, payable(0)]\n )\n : emitClaimReceivedAndReturn(\n Result.NoConflict,\n [claim, bytes32(0)],\n [sender, payable(0)]\n );\n }\n\n /// @notice emits dispute ended event and then return\n /// @param result to be emitted and returned\n /// @param claims to be emitted and returned\n /// @param validators to be emitted and returned\n /// @dev this function existis to make code more clear/concise\n function emitDisputeEndedAndReturn(\n Result result,\n bytes32[2] memory claims,\n address payable[2] memory validators\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n emit DisputeEnded(result, claims, validators);\n return (result, claims, validators);\n }\n\n /// @notice emits claim received event and then return\n /// @param result to be emitted and returned\n /// @param claims to be emitted and returned\n /// @param validators to be emitted and returned\n /// @dev this function existis to make code more clear/concise\n function emitClaimReceivedAndReturn(\n Result result,\n bytes32[2] memory claims,\n address payable[2] memory validators\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n emit ClaimReceived(result, claims, validators);\n return (result, claims, validators);\n }\n\n /// @notice only call this function when a claim has been finalized\n /// Either a consensus has been reached or challenge period has past\n /// @param ds pointer to diamond storage\n function claimFinalizedIncreaseCounts(DiamondStorage storage ds) internal {\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\n for (uint256 i; i < ds.validators.length; i++) {\n // if a validator agrees with the current claim\n if ((agreementMask & (1 << i)) != 0) {\n // increase #claims by 1\n ds.claimsMask = ds.claimsMask.increaseNumClaims(i, 1);\n }\n }\n }\n\n /// @notice removes a validator\n /// @param ds diamond storage pointer\n /// @param validator address of validator to be removed\n function removeValidator(DiamondStorage storage ds, address validator)\n internal\n {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n for (uint256 i; i < ds.validators.length; i++) {\n if (validator == ds.validators[i]) {\n // put address(0) in validators position\n ds.validators[i] = payable(0);\n // remove the validator from ValidatorManager's claimsMask\n ds.claimsMask = ds.claimsMask.removeValidator(i);\n // remove the validator from FeeManager's claimsMask (#redeems)\n feeManagerDS.removeValidator(i);\n break;\n }\n }\n }\n\n /// @notice check if consensus has been reached\n /// @param ds pointer to diamond storage\n function isConsensus(DiamondStorage storage ds)\n internal\n view\n returns (bool)\n {\n ClaimsMask claimsMask = ds.claimsMask;\n return\n claimsMask.getAgreementMask() == claimsMask.getConsensusGoalMask();\n }\n\n /// @notice get one of the validators that agreed with current claim\n /// @param ds diamond storage pointer\n /// @return validator that agreed with current claim\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\n internal\n view\n returns (address payable)\n {\n // TODO: we are always getting the first validator\n // on the array that agrees with the current claim to enter a dispute\n // should this be random?\n uint256 agreementMask = ds.claimsMask.getAgreementMask();\n for (uint256 i; i < ds.validators.length; i++) {\n if (agreementMask & (1 << i) != 0) {\n return ds.validators[i];\n }\n }\n revert(\"Agreeing validator not found\");\n }\n\n /// @notice updates mask of validators that agreed with current claim\n /// @param ds diamond storage pointer\n /// @param sender address of validator that will be included in mask\n function updateClaimAgreementMask(\n DiamondStorage storage ds,\n address payable sender\n ) internal {\n uint256 validatorIndex = getValidatorIndex(ds, sender);\n ds.claimsMask = ds.claimsMask.setAgreementMask(validatorIndex);\n }\n\n /// @notice check if the sender is a validator\n /// @param ds pointer to diamond storage\n /// @param sender sender address\n function isValidator(DiamondStorage storage ds, address sender)\n internal\n view\n returns (bool)\n {\n require(sender != address(0), \"address 0\");\n\n for (uint256 i; i < ds.validators.length; i++) {\n if (sender == ds.validators[i]) return true;\n }\n\n return false;\n }\n\n /// @notice find the validator and return the index or revert\n /// @param ds pointer to diamond storage\n /// @param sender validator address\n /// @return validator index or revert\n function getValidatorIndex(DiamondStorage storage ds, address sender)\n internal\n view\n returns (uint256)\n {\n require(sender != address(0), \"address 0\");\n for (uint256 i; i < ds.validators.length; i++) {\n if (sender == ds.validators[i]) return i;\n }\n revert(\"validator not found\");\n }\n\n /// @notice get number of claims the sender has made\n /// @param ds pointer to diamond storage\n /// @param _sender validator address\n /// @return #claims\n function getNumberOfClaimsByAddress(\n DiamondStorage storage ds,\n address payable _sender\n ) internal view returns (uint256) {\n for (uint256 i; i < ds.validators.length; i++) {\n if (_sender == ds.validators[i]) {\n return getNumberOfClaimsByIndex(ds, i);\n }\n }\n // if validator not found\n return 0;\n }\n\n /// @notice get number of claims by the index in the validator set\n /// @param ds pointer to diamond storage\n /// @param index the index in validator set\n /// @return #claims\n function getNumberOfClaimsByIndex(DiamondStorage storage ds, uint256 index)\n internal\n view\n returns (uint256)\n {\n return ds.claimsMask.getNumClaims(index);\n }\n\n /// @notice get the maximum number of validators defined in validator manager\n /// @param ds pointer to diamond storage\n /// @return the maximum number of validators\n function getMaxNumValidators(DiamondStorage storage ds)\n internal\n view\n returns (uint256)\n {\n return ds.maxNumValidators;\n }\n}\n" + }, + "contracts/libraries/LibDisputeManager.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Dispute Manager library\npragma solidity ^0.8.0;\n\nimport {LibRollups} from \"../libraries/LibRollups.sol\";\n\nlibrary LibDisputeManager {\n using LibRollups for LibRollups.DiamondStorage;\n\n /// @notice initiates a dispute betweent two players\n /// @param claims conflicting claims\n /// @param claimers addresses of senders of conflicting claim\n /// @dev this is a mock implementation that just gives the win\n /// to the address in the first posititon of claimers array\n function initiateDispute(\n bytes32[2] memory claims,\n address payable[2] memory claimers\n ) internal {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n rollupsDS.resolveDispute(claimers[0], claimers[1], claims[0]);\n }\n}\n" + }, + "contracts/libraries/LibClaimsMask.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title ClaimsMask library\npragma solidity >=0.8.8;\n\n// ClaimsMask is used to keep track of the number of claims for up to 8 validators\n// | agreement mask | consensus goal mask | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\n// | 8 bits | 8 bits | 30 bits | 30 bits | ... | 30 bits |\n// In Validator Manager, #claims_validator indicates the #claims the validator has made.\n// In Fee Manager, #claims_validator indicates the #claims the validator has redeemed. In this case,\n// agreement mask and consensus goal mask are not used.\n\ntype ClaimsMask is uint256;\n\nlibrary LibClaimsMask {\n uint256 constant claimsBitLen = 30; // #bits used for each #claims\n\n /// @notice this function creates a new ClaimsMask variable with value _value\n /// @param _value the value following the format of ClaimsMask\n function newClaimsMask(uint256 _value) internal pure returns (ClaimsMask) {\n return ClaimsMask.wrap(_value);\n }\n\n /// @notice this function creates a new ClaimsMask variable with the consensus goal mask set,\n /// according to the number of validators\n /// @param _numValidators the number of validators\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\n internal\n pure\n returns (ClaimsMask)\n {\n require(_numValidators <= 8, \"up to 8 validators\");\n uint256 consensusMask = (1 << _numValidators) - 1;\n return ClaimsMask.wrap(consensusMask << 240); // 256 - 8 - 8 = 240\n }\n\n /// @notice this function returns the #claims for the specified validator\n /// @param _claimsMask the ClaimsMask value\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\n /// this index can be obtained though `getNumberOfClaimsByIndex` function in Validator Manager\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\n internal\n pure\n returns (uint256)\n {\n require(_validatorIndex < 8, \"index out of range\");\n uint256 bitmask = (1 << claimsBitLen) - 1;\n return\n (ClaimsMask.unwrap(_claimsMask) >>\n (claimsBitLen * _validatorIndex)) & bitmask;\n }\n\n /// @notice this function increases the #claims for the specified validator\n /// @param _claimsMask the ClaimsMask value\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\n /// @param _value the increase amount\n function increaseNumClaims(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex,\n uint256 _value\n ) internal pure returns (ClaimsMask) {\n require(_validatorIndex < 8, \"index out of range\");\n uint256 currentNum = getNumClaims(_claimsMask, _validatorIndex);\n uint256 newNum = currentNum + _value; // overflows checked by default with sol0.8\n return setNumClaims(_claimsMask, _validatorIndex, newNum);\n }\n\n /// @notice this function sets the #claims for the specified validator\n /// @param _claimsMask the ClaimsMask value\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\n /// @param _value the set value\n function setNumClaims(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex,\n uint256 _value\n ) internal pure returns (ClaimsMask) {\n require(_validatorIndex < 8, \"index out of range\");\n require(_value <= ((1 << claimsBitLen) - 1), \"ClaimsMask Overflow\");\n uint256 bitmask = ~(((1 << claimsBitLen) - 1) <<\n (claimsBitLen * _validatorIndex));\n uint256 clearedClaimsMask = ClaimsMask.unwrap(_claimsMask) & bitmask;\n _claimsMask = ClaimsMask.wrap(\n clearedClaimsMask | (_value << (claimsBitLen * _validatorIndex))\n );\n return _claimsMask;\n }\n\n /// @notice get consensus goal mask\n /// @param _claimsMask the ClaimsMask value\n function clearAgreementMask(ClaimsMask _claimsMask)\n internal\n pure\n returns (ClaimsMask)\n {\n uint256 clearedMask = ClaimsMask.unwrap(_claimsMask) & ((1 << 248) - 1); // 256 - 8 = 248\n return ClaimsMask.wrap(clearedMask);\n }\n\n /// @notice get the entire agreement mask\n /// @param _claimsMask the ClaimsMask value\n function getAgreementMask(ClaimsMask _claimsMask)\n internal\n pure\n returns (uint256)\n {\n return (ClaimsMask.unwrap(_claimsMask) >> 248); // get the first 8 bits\n }\n\n /// @notice check if a validator has already claimed\n /// @param _claimsMask the ClaimsMask value\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\n internal\n pure\n returns (bool)\n {\n // get the first 8 bits. Then & operation on the validator's bit to see if it's set\n return\n (((ClaimsMask.unwrap(_claimsMask) >> 248) >> _validatorIndex) &\n 1) != 0;\n }\n\n /// @notice set agreement mask for the specified validator\n /// @param _claimsMask the ClaimsMask value\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\n internal\n pure\n returns (ClaimsMask)\n {\n require(_validatorIndex < 8, \"index out of range\");\n uint256 setMask = (ClaimsMask.unwrap(_claimsMask) |\n (1 << (248 + _validatorIndex))); // 256 - 8 = 248\n return ClaimsMask.wrap(setMask);\n }\n\n /// @notice get the entire consensus goal mask\n /// @param _claimsMask the ClaimsMask value\n function getConsensusGoalMask(ClaimsMask _claimsMask)\n internal\n pure\n returns (uint256)\n {\n return ((ClaimsMask.unwrap(_claimsMask) << 8) >> 248); // get the second 8 bits\n }\n\n /// @notice remove validator from the ClaimsMask\n /// @param _claimsMask the ClaimsMask value\n /// @param _validatorIndex index of the validator in the validator array, starting from 0\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\n internal\n pure\n returns (ClaimsMask)\n {\n require(_validatorIndex < 8, \"index out of range\");\n uint256 claimsMaskValue = ClaimsMask.unwrap(_claimsMask);\n // remove validator from agreement bitmask\n uint256 zeroMask = ~(1 << (_validatorIndex + 248)); // 256 - 8 = 248\n claimsMaskValue = (claimsMaskValue & zeroMask);\n // remove validator from consensus goal mask\n zeroMask = ~(1 << (_validatorIndex + 240)); // 256 - 8 - 8 = 240\n claimsMaskValue = (claimsMaskValue & zeroMask);\n // remove validator from #claims\n return\n setNumClaims(ClaimsMask.wrap(claimsMaskValue), _validatorIndex, 0);\n }\n}\n" + }, + "contracts/libraries/LibFeeManager.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Fee Manager library\npragma solidity ^0.8.0;\n\nimport {LibValidatorManager} from \"../libraries/LibValidatorManager.sol\";\nimport {LibClaimsMask, ClaimsMask} from \"../libraries/LibClaimsMask.sol\";\nimport {IBank} from \"../IBank.sol\";\n\nlibrary LibFeeManager {\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\n using LibFeeManager for LibFeeManager.DiamondStorage;\n using LibClaimsMask for ClaimsMask;\n\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"FeeManager.diamond.storage\");\n\n struct DiamondStorage {\n address owner; // owner of Fee Manager\n uint256 feePerClaim;\n IBank bank; // bank that holds the tokens to pay validators\n bool lock; // reentrancy lock\n // A bit set used for up to 8 validators.\n // The first 16 bits are not used to keep compatibility with the validator manager contract.\n // The following every 30 bits are used to indicate the number of total claims each validator has made\n // | not used | #claims_validator7 | #claims_validator6 | ... | #claims_validator0 |\n // | 16 bits | 30 bits | 30 bits | ... | 30 bits |\n ClaimsMask numClaimsRedeemed;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function onlyOwner(DiamondStorage storage ds) internal view {\n require(ds.owner == msg.sender, \"caller is not the owner\");\n }\n\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\n /// @param ds pointer to FeeManager's diamond storage\n /// @param _validator address of the validator\n function numClaimsRedeemable(DiamondStorage storage ds, address _validator)\n internal\n view\n returns (uint256)\n {\n require(_validator != address(0), \"address should not be 0\");\n\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\n uint256 totalClaims = validatorManagerDS.claimsMask.getNumClaims(\n valIndex\n );\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\n\n // underflow checked by default with sol0.8\n // which means if the validator is removed, calling this function will\n // either return 0 or revert\n return totalClaims - redeemedClaims;\n }\n\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\n /// @param ds pointer to FeeManager's diamond storage\n /// @param _validator address of the validator\n function getNumClaimsRedeemed(DiamondStorage storage ds, address _validator)\n internal\n view\n returns (uint256)\n {\n require(_validator != address(0), \"address should not be 0\");\n\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\n uint256 redeemedClaims = ds.numClaimsRedeemed.getNumClaims(valIndex);\n\n return redeemedClaims;\n }\n\n /// @notice contract owner can reset the value of fee per claim\n /// @param ds pointer to FeeManager's diamond storage\n /// @param _value the new value of fee per claim\n function resetFeePerClaim(DiamondStorage storage ds, uint256 _value)\n internal\n {\n // before resetting the feePerClaim, pay fees for all validators as per current rates\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n for (\n uint256 valIndex;\n valIndex < validatorManagerDS.maxNumValidators;\n valIndex++\n ) {\n address validator = validatorManagerDS.validators[valIndex];\n if (validator != address(0)) {\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(validator);\n if (nowRedeemingClaims > 0) {\n ds.numClaimsRedeemed = ds\n .numClaimsRedeemed\n .increaseNumClaims(valIndex, nowRedeemingClaims);\n\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\n ds.bank.transferTokens(validator, feesToSend); // will revert if transfer fails\n // emit the number of claimed being redeemed, instead of the amount of tokens\n emit FeeRedeemed(validator, nowRedeemingClaims);\n }\n }\n }\n ds.feePerClaim = _value;\n emit FeePerClaimReset(_value);\n }\n\n /// @notice this function can be called to redeem fees for validators\n /// @param ds pointer to FeeManager's diamond storage\n /// @param _validator address of the validator that is redeeming\n function redeemFee(DiamondStorage storage ds, address _validator) internal {\n // follow the Checks-Effects-Interactions pattern for security\n\n // ** checks **\n uint256 nowRedeemingClaims = ds.numClaimsRedeemable(_validator);\n require(nowRedeemingClaims > 0, \"nothing to redeem yet\");\n\n // ** effects **\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n uint256 valIndex = validatorManagerDS.getValidatorIndex(_validator); // will revert if not found\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.increaseNumClaims(\n valIndex,\n nowRedeemingClaims\n );\n\n // ** interactions **\n uint256 feesToSend = nowRedeemingClaims * ds.feePerClaim; // number of erc20 tokens to send\n ds.bank.transferTokens(_validator, feesToSend); // will revert if transfer fails\n // emit the number of claimed being redeemed, instead of the amount of tokens\n emit FeeRedeemed(_validator, nowRedeemingClaims);\n }\n\n /// @notice removes a validator\n /// @param ds diamond storage pointer\n /// @param index index of validator to be removed\n function removeValidator(DiamondStorage storage ds, uint256 index)\n internal\n {\n ds.numClaimsRedeemed = ds.numClaimsRedeemed.setNumClaims(index, 0);\n }\n\n /// @notice emitted on resetting feePerClaim\n event FeePerClaimReset(uint256 value);\n\n /// @notice emitted on ERC20 funds redeemed by validator\n event FeeRedeemed(address validator, uint256 claims);\n}\n" + }, + "contracts/facets/RollupsFacet.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Rollups facet\npragma solidity ^0.8.0;\n\nimport {IRollups, Phase} from \"../interfaces/IRollups.sol\";\nimport {Result} from \"../interfaces/IValidatorManager.sol\";\n\nimport {LibRollups} from \"../libraries/LibRollups.sol\";\nimport {LibInput} from \"../libraries/LibInput.sol\";\nimport {LibOutput} from \"../libraries/LibOutput.sol\";\nimport {LibValidatorManager} from \"../libraries/LibValidatorManager.sol\";\n\ncontract RollupsFacet is IRollups {\n ////\n // All claims agreed OR challenge period ended\n // functions: claim() or finalizeEpoch()\n // +--------------------------------------------------+\n // | |\n // +--------v-----------+ new input after IPAD +---------+----------+\n // | +--------------------------->+ |\n // START ---> | Input Accumulation | firt claim after IPAD | Awaiting Consensus |\n // | +--------------------------->+ |\n // +-+------------------+ +-----------------+--+\n // ^ ^ |\n // | dispute resolved | |\n // | dispute resolved before challenge | |\n // | after challenge +--------------------+ period ended | |\n // | period ended | +---------------------+ |\n // +----------------------+ Awaiting Dispute | |\n // | +<-----------------------+\n // +--------------------+ conflicting claim\n ///\n\n using LibRollups for LibRollups.DiamondStorage;\n using LibInput for LibInput.DiamondStorage;\n using LibOutput for LibOutput.DiamondStorage;\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\n\n /// @notice claim the result of current epoch\n /// @param _epochHash hash of epoch\n /// @dev ValidatorManager makes sure that msg.sender is allowed\n /// and that claim != bytes32(0)\n /// TODO: add signatures for aggregated claims\n function claim(bytes32 _epochHash) public override {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n\n Result result;\n bytes32[2] memory claims;\n address payable[2] memory claimers;\n\n Phase currentPhase = Phase(rollupsDS.currentPhase_int);\n uint256 inputAccumulationStart = rollupsDS.inputAccumulationStart;\n uint256 inputDuration = rollupsDS.inputDuration;\n\n if (\n currentPhase == Phase.InputAccumulation &&\n block.timestamp > inputAccumulationStart + inputDuration\n ) {\n currentPhase = Phase.AwaitingConsensus;\n rollupsDS.currentPhase_int = uint32(Phase.AwaitingConsensus);\n emit PhaseChange(Phase.AwaitingConsensus);\n\n // warns input of new epoch\n inputDS.onNewInputAccumulation();\n // update timestamp of sealing epoch proposal\n rollupsDS.sealingEpochTimestamp = uint32(block.timestamp);\n }\n\n require(\n currentPhase == Phase.AwaitingConsensus,\n \"Phase != AwaitingConsensus\"\n );\n (result, claims, claimers) = validatorManagerDS.onClaim(\n payable(msg.sender),\n _epochHash\n );\n\n // emit the claim event before processing it\n // so if the epoch is finalized in this claim (consensus)\n // the number of final epochs doesnt gets contaminated\n emit Claim(\n outputDS.getNumberOfFinalizedEpochs(),\n msg.sender,\n _epochHash\n );\n\n rollupsDS.resolveValidatorResult(result, claims, claimers);\n }\n\n /// @notice finalize epoch after timeout\n /// @dev can only be called if challenge period is over\n function finalizeEpoch() public override {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n\n Phase currentPhase = Phase(rollupsDS.currentPhase_int);\n require(\n currentPhase == Phase.AwaitingConsensus,\n \"Phase != Awaiting Consensus\"\n );\n\n uint256 sealingEpochTimestamp = rollupsDS.sealingEpochTimestamp;\n uint256 challengePeriod = rollupsDS.challengePeriod;\n require(\n block.timestamp > sealingEpochTimestamp + challengePeriod,\n \"Challenge period not over\"\n );\n\n require(\n validatorManagerDS.currentClaim != bytes32(0),\n \"No Claim to be finalized\"\n );\n\n rollupsDS.startNewEpoch();\n }\n\n /// @notice returns index of current (accumulating) epoch\n /// @return index of current epoch\n /// @dev if phase is input accumulation, then the epoch number is length\n /// of finalized epochs array, else there are two non finalized epochs,\n /// one awaiting consensus/dispute and another accumulating input\n function getCurrentEpoch() public view override returns (uint256) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return rollupsDS.getCurrentEpoch();\n }\n\n /// @notice returns the current phase\n function getCurrentPhase() public view returns (Phase) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return Phase(rollupsDS.currentPhase_int);\n }\n\n /// @notice returns the input accumulation start timestamp\n function getInputAccumulationStart() public view returns (uint256) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return uint256(rollupsDS.inputAccumulationStart);\n }\n\n /// @notice returns the sealing epoch timestamp\n function getSealingEpochTimestamp() public view returns (uint256) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return uint256(rollupsDS.sealingEpochTimestamp);\n }\n\n /// @notice returns the input duration in seconds\n function getInputDuration() public view returns (uint256) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return uint256(rollupsDS.inputDuration);\n }\n\n /// @notice returns the challenge period in seconds\n function getChallengePeriod() public view returns (uint256) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return uint256(rollupsDS.challengePeriod);\n }\n\n /// @notice returns the machine's template hash\n function getTemplateHash() public view returns (bytes32) {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n return rollupsDS.templateHash;\n }\n}\n" + }, + "contracts/facets/ValidatorManagerFacet.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Validator Manager facet\npragma solidity ^0.8.0;\n\nimport {IValidatorManager} from \"../interfaces/IValidatorManager.sol\";\n\nimport {LibValidatorManager} from \"../libraries/LibValidatorManager.sol\";\n\nimport {LibClaimsMask, ClaimsMask} from \"../libraries/LibClaimsMask.sol\";\n\ncontract ValidatorManagerFacet is IValidatorManager {\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\n using LibClaimsMask for ClaimsMask;\n\n /// @notice get agreement mask\n /// @return current state of agreement mask\n function getAgreementMask() public view returns (uint256) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.claimsMask.getAgreementMask();\n }\n\n /// @notice get consensus goal mask\n /// @return current consensus goal mask\n function getConsensusGoalMask() public view returns (uint256) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.claimsMask.getConsensusGoalMask();\n }\n\n /// @notice get current claim\n /// @return current claim\n function getCurrentClaim() public view override returns (bytes32) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.currentClaim;\n }\n\n /// @notice get number of claims the sender has made\n /// @param _sender validator address\n /// @return #claims\n function getNumberOfClaimsByAddress(address payable _sender)\n public\n view\n returns (uint256)\n {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.getNumberOfClaimsByAddress(_sender);\n }\n\n /// @notice find the validator and return the index or revert\n /// @param _sender validator address\n /// @return validator index or revert\n function getValidatorIndex(address _sender) public view returns (uint256) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.getValidatorIndex(_sender);\n }\n\n /// @notice get number of claims by the index in the validator set\n /// @param _index the index in validator set\n /// @return #claims\n function getNumberOfClaimsByIndex(uint256 _index)\n public\n view\n returns (uint256)\n {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.getNumberOfClaimsByIndex(_index);\n }\n\n /// @notice get the maximum number of validators defined in validator manager\n /// @return the maximum number of validators\n function getMaxNumValidators() public view returns (uint256) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.getMaxNumValidators();\n }\n}\n" + }, + "contracts/test_helper/TestLibClaimsMask.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Test ClaimsMask library\npragma solidity >=0.8.8;\n\nimport \"../libraries/LibClaimsMask.sol\";\n\ncontract TestLibClaimsMask {\n function newClaimsMask(uint256 _value) public pure returns (ClaimsMask) {\n return LibClaimsMask.newClaimsMask(_value);\n }\n\n function newClaimsMaskWithConsensusGoalSet(uint256 _numValidators)\n public\n pure\n returns (ClaimsMask)\n {\n return LibClaimsMask.newClaimsMaskWithConsensusGoalSet(_numValidators);\n }\n\n function getNumClaims(ClaimsMask _claimsMask, uint256 _validatorIndex)\n public\n pure\n returns (uint256)\n {\n return LibClaimsMask.getNumClaims(_claimsMask, _validatorIndex);\n }\n\n function increaseNumClaims(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex,\n uint256 _value\n ) public pure returns (ClaimsMask) {\n return\n LibClaimsMask.increaseNumClaims(\n _claimsMask,\n _validatorIndex,\n _value\n );\n }\n\n function setNumClaims(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex,\n uint256 _value\n ) public pure returns (ClaimsMask) {\n return LibClaimsMask.setNumClaims(_claimsMask, _validatorIndex, _value);\n }\n\n function clearAgreementMask(ClaimsMask _claimsMask)\n public\n pure\n returns (ClaimsMask)\n {\n return LibClaimsMask.clearAgreementMask(_claimsMask);\n }\n\n function getAgreementMask(ClaimsMask _claimsMask)\n public\n pure\n returns (uint256)\n {\n return LibClaimsMask.getAgreementMask(_claimsMask);\n }\n\n function alreadyClaimed(ClaimsMask _claimsMask, uint256 _validatorIndex)\n public\n pure\n returns (bool)\n {\n return LibClaimsMask.alreadyClaimed(_claimsMask, _validatorIndex);\n }\n\n function setAgreementMask(ClaimsMask _claimsMask, uint256 _validatorIndex)\n public\n pure\n returns (ClaimsMask)\n {\n return LibClaimsMask.setAgreementMask(_claimsMask, _validatorIndex);\n }\n\n function getConsensusGoalMask(ClaimsMask _claimsMask)\n public\n pure\n returns (uint256)\n {\n return LibClaimsMask.getConsensusGoalMask(_claimsMask);\n }\n\n function removeValidator(ClaimsMask _claimsMask, uint256 _validatorIndex)\n public\n pure\n returns (ClaimsMask)\n {\n return LibClaimsMask.removeValidator(_claimsMask, _validatorIndex);\n }\n}\n" + }, + "contracts/facets/DebugFacet.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Debug facet\npragma solidity ^0.8.0;\n\nimport {Result} from \"../interfaces/IValidatorManager.sol\";\nimport {Phase} from \"../interfaces/IRollups.sol\";\nimport {IEtherPortal} from \"../interfaces/IEtherPortal.sol\";\nimport {IERC20Portal} from \"../interfaces/IERC20Portal.sol\";\nimport {IERC721Portal} from \"../interfaces/IERC721Portal.sol\";\n\nimport {LibRollups} from \"../libraries/LibRollups.sol\";\nimport {LibInput} from \"../libraries/LibInput.sol\";\nimport {LibOutput} from \"../libraries/LibOutput.sol\";\nimport {LibValidatorManager} from \"../libraries/LibValidatorManager.sol\";\nimport {LibFeeManager} from \"../libraries/LibFeeManager.sol\";\nimport {LibClaimsMask, ClaimsMask} from \"../libraries/LibClaimsMask.sol\";\n\ncontract DebugFacet {\n using LibRollups for LibRollups.DiamondStorage;\n using LibInput for LibInput.DiamondStorage;\n using LibOutput for LibOutput.DiamondStorage;\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\n using LibFeeManager for LibFeeManager.DiamondStorage;\n using LibClaimsMask for ClaimsMask;\n\n function _setCurrentPhase(Phase _phase) public {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n rollupsDS.currentPhase_int = uint32(_phase);\n }\n\n function _getValidators() public view returns (address payable[] memory) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.validators;\n }\n\n function _onClaim(address payable _sender, bytes32 _claim)\n public\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.onClaim(_sender, _claim);\n }\n\n /// @notice called when a dispute ends in rollups\n /// @param _winner address of dispute winner\n /// @param _loser address of dispute loser\n /// @param _winningClaim the winning claim\n /// @return result of dispute being finished\n function _onDisputeEnd(\n address payable _winner,\n address payable _loser,\n bytes32 _winningClaim\n )\n public\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.onDisputeEnd(_winner, _loser, _winningClaim);\n }\n\n /// @notice called when a new epoch starts\n /// @return current claim\n function _onNewEpochVM() public returns (bytes32) {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n return validatorManagerDS.onNewEpoch();\n }\n\n function _getInputDriveSize() public view returns (uint256) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n return inputDS.inputDriveSize;\n }\n\n function _etherWithdrawal(bytes calldata _data) public returns (bool) {\n IEtherPortal etherPortal = IEtherPortal(address(this));\n return etherPortal.etherWithdrawal(_data);\n }\n\n function _onNewEpochOutput(bytes32 epochHash) public {\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n outputDS.onNewEpoch(epochHash);\n }\n\n function _erc721Withdrawal(bytes calldata _data) public returns (bool) {\n IERC721Portal erc721Portal = IERC721Portal(address(this));\n return erc721Portal.erc721Withdrawal(_data);\n }\n\n function _getFeePerClaim() public view returns (uint256) {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n return feeManagerDS.feePerClaim;\n }\n\n function _setNumClaims(uint256 _validatorIndex, uint256 _value) public {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n validatorManagerDS.claimsMask = validatorManagerDS\n .claimsMask\n .setNumClaims(_validatorIndex, _value);\n }\n\n function _getNumRedeems(uint256 _validatorIndex)\n public\n view\n returns (uint256)\n {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n return feeManagerDS.numClaimsRedeemed.getNumClaims(_validatorIndex);\n }\n\n /// @notice emitted on Claim received\n event ClaimReceived(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on Dispute end\n event DisputeEnded(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on new Epoch\n event NewEpoch(bytes32 claim);\n}\n" + }, + "contracts/interfaces/IEtherPortal.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Ether Portal interface\npragma solidity >=0.7.0;\n\ninterface IEtherPortal {\n /// @notice deposit an amount of Ether in the portal and create Ether in L2\n /// @param _data information to be interpreted by L2\n /// @return hash of input generated by deposit\n function etherDeposit(bytes calldata _data)\n external\n payable\n returns (bytes32);\n\n /// @notice withdraw an amount of Ether from the portal\n /// @param _data data with withdrawal information\n /// @dev can only be called by the Rollups contract\n function etherWithdrawal(bytes calldata _data) external returns (bool);\n\n /// @notice emitted on Ether deposited\n event EtherDeposited(address sender, uint256 amount, bytes data);\n\n /// @notice emitted on Ether withdrawal\n event EtherWithdrawn(address payable receiver, uint256 amount);\n}\n" + }, + "contracts/interfaces/IERC20Portal.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Generic ERC20 Portal interface\npragma solidity >=0.7.0;\n\ninterface IERC20Portal {\n /// @notice deposit an amount of a generic ERC20 token in the portal and create tokens in L2\n /// @param _ERC20 address of the ERC20 token contract\n /// @param _amount amount of the ERC20 token to be deposited\n /// @param _data information to be interpreted by L2\n /// @return hash of input generated by deposit\n function erc20Deposit(\n address _ERC20,\n uint256 _amount,\n bytes calldata _data\n ) external returns (bytes32);\n\n /// @notice emitted on ERC20 deposited\n event ERC20Deposited(\n address ERC20,\n address sender,\n uint256 amount,\n bytes data\n );\n}\n" + }, + "contracts/facets/OutputFacet.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Output facet\npragma solidity ^0.8.0;\n\nimport {Bitmask} from \"@cartesi/util/contracts/Bitmask.sol\";\nimport {Merkle} from \"@cartesi/util/contracts/Merkle.sol\";\n\nimport {IOutput, OutputValidityProof} from \"../interfaces/IOutput.sol\";\n\nimport {LibOutput} from \"../libraries/LibOutput.sol\";\nimport {LibFeeManager} from \"../libraries/LibFeeManager.sol\";\n\ncontract OutputFacet is IOutput {\n using LibOutput for LibOutput.DiamondStorage;\n\n // Here we only need 248 bits as keys in the mapping, but we use 256 bits for gas optimization\n using Bitmask for mapping(uint256 => uint256);\n\n uint256 constant KECCAK_LOG2_SIZE = 5; // keccak log2 size\n\n // max size of voucher metadata memory range 32 * (2^16) bytes\n uint256 constant VOUCHER_METADATA_LOG2_SIZE = 21;\n // max size of epoch voucher memory range 32 * (2^32) bytes\n uint256 constant EPOCH_VOUCHER_LOG2_SIZE = 37;\n\n // max size of notice metadata memory range 32 * (2^16) bytes\n uint256 constant NOTICE_METADATA_LOG2_SIZE = 21;\n // max size of epoch notice memory range 32 * (2^32) bytes\n uint256 constant EPOCH_NOTICE_LOG2_SIZE = 37;\n\n /// @notice functions modified by noReentrancy are not subject to recursion\n modifier noReentrancy() {\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n\n require(!outputDS.lock, \"reentrancy not allowed\");\n outputDS.lock = true;\n _;\n outputDS.lock = false;\n }\n\n /// @notice executes voucher\n /// @param _destination address that will execute the payload\n /// @param _payload payload to be executed by destination\n /// @param _v validity proof for this encoded voucher\n /// @return true if voucher was executed successfully\n /// @dev vouchers can only be executed once\n function executeVoucher(\n address _destination,\n bytes calldata _payload,\n OutputValidityProof calldata _v\n ) public override noReentrancy returns (bool) {\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n\n // avoid a malicious DApp developer from draining the Fee Manager's bank account\n require(_destination != address(feeManagerDS.bank), \"bad destination\");\n\n bytes memory encodedVoucher = abi.encode(_destination, _payload);\n\n // check if validity proof matches the voucher provided\n isValidVoucherProof(\n encodedVoucher,\n outputDS.epochHashes[_v.epochIndex],\n _v\n );\n\n uint256 voucherPosition = getBitMaskPosition(\n _v.outputIndex,\n _v.inputIndex,\n _v.epochIndex\n );\n\n // check if voucher has been executed\n require(\n !outputDS.voucherBitmask.getBit(voucherPosition),\n \"re-execution not allowed\"\n );\n\n // execute voucher\n (bool succ, ) = _destination.call(_payload);\n\n // if properly executed, mark it as executed and emit event\n if (succ) {\n outputDS.voucherBitmask.setBit(voucherPosition, true);\n emit VoucherExecuted(voucherPosition);\n }\n\n return succ;\n }\n\n /// @notice isValidProof reverts if the proof is invalid\n /// @dev _outputsEpochRootHash must be _v.vouchersEpochRootHash or\n /// or _v.noticesEpochRootHash\n function isValidProof(\n bytes memory _encodedOutput,\n bytes32 _epochHash,\n bytes32 _outputsEpochRootHash,\n uint256 _outputEpochLog2Size,\n uint256 _outputHashesLog2Size,\n OutputValidityProof calldata _v\n ) internal pure {\n // prove that outputs hash is represented in a finalized epoch\n require(\n keccak256(\n abi.encodePacked(\n _v.vouchersEpochRootHash,\n _v.noticesEpochRootHash,\n _v.machineStateHash\n )\n ) == _epochHash,\n \"epochHash incorrect\"\n );\n\n // prove that output metadata memory range is contained in epoch's output memory range\n require(\n Merkle.getRootAfterReplacementInDrive(\n getIntraDrivePosition(_v.inputIndex, KECCAK_LOG2_SIZE),\n KECCAK_LOG2_SIZE,\n _outputEpochLog2Size,\n keccak256(abi.encodePacked(_v.outputHashesRootHash)),\n _v.outputHashesInEpochSiblings\n ) == _outputsEpochRootHash,\n \"outputsEpochRootHash incorrect\"\n );\n\n // The hash of the output is converted to bytes (abi.encode) and\n // treated as data. The metadata output memory range stores that data while\n // being indifferent to its contents. To prove that the received\n // output is contained in the metadata output memory range we need to\n // prove that x, where:\n // x = keccak(\n // keccak(\n // keccak(hashOfOutput[0:7]),\n // keccak(hashOfOutput[8:15])\n // ),\n // keccak(\n // keccak(hashOfOutput[16:23]),\n // keccak(hashOfOutput[24:31])\n // )\n // )\n // is contained in it. We can't simply use hashOfOutput because the\n // log2size of the leaf is three (8 bytes) not five (32 bytes)\n bytes32 merkleRootOfHashOfOutput = Merkle.getMerkleRootFromBytes(\n abi.encodePacked(keccak256(_encodedOutput)),\n KECCAK_LOG2_SIZE\n );\n\n // prove that merkle root hash of bytes(hashOfOutput) is contained\n // in the output metadata array memory range\n require(\n Merkle.getRootAfterReplacementInDrive(\n getIntraDrivePosition(_v.outputIndex, KECCAK_LOG2_SIZE),\n KECCAK_LOG2_SIZE,\n _outputHashesLog2Size,\n merkleRootOfHashOfOutput,\n _v.keccakInHashesSiblings\n ) == _v.outputHashesRootHash,\n \"outputHashesRootHash incorrect\"\n );\n }\n\n /// @notice isValidVoucherProof reverts if the proof is invalid\n function isValidVoucherProof(\n bytes memory _encodedVoucher,\n bytes32 _epochHash,\n OutputValidityProof calldata _v\n ) public pure {\n isValidProof(\n _encodedVoucher,\n _epochHash,\n _v.vouchersEpochRootHash,\n EPOCH_VOUCHER_LOG2_SIZE,\n VOUCHER_METADATA_LOG2_SIZE,\n _v\n );\n }\n\n /// @notice isValidNoticeProof reverts if the proof is invalid\n function isValidNoticeProof(\n bytes memory _encodedNotice,\n bytes32 _epochHash,\n OutputValidityProof calldata _v\n ) public pure {\n isValidProof(\n _encodedNotice,\n _epochHash,\n _v.noticesEpochRootHash,\n EPOCH_NOTICE_LOG2_SIZE,\n NOTICE_METADATA_LOG2_SIZE,\n _v\n );\n }\n\n /// @notice get voucher position on bitmask\n /// @param _voucher of voucher inside the input\n /// @param _input which input, inside the epoch, the voucher belongs to\n /// @param _epoch which epoch the voucher belongs to\n /// @return position of that voucher on bitmask\n function getBitMaskPosition(\n uint256 _voucher,\n uint256 _input,\n uint256 _epoch\n ) public pure returns (uint256) {\n // voucher * 2 ** 128 + input * 2 ** 64 + epoch\n // this can't overflow because its impossible to have > 2**128 vouchers\n return (((_voucher << 128) | (_input << 64)) | _epoch);\n }\n\n /// @notice returns the position of a intra memory range on a memory range\n // with contents with the same size\n /// @param _index index of intra memory range\n /// @param _log2Size of intra memory range\n function getIntraDrivePosition(uint256 _index, uint256 _log2Size)\n public\n pure\n returns (uint256)\n {\n return (_index << _log2Size);\n }\n\n /// @notice get number of finalized epochs\n function getNumberOfFinalizedEpochs()\n public\n view\n override\n returns (uint256)\n {\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n return outputDS.getNumberOfFinalizedEpochs();\n }\n\n /// @notice get log2 size of voucher metadata memory range\n function getVoucherMetadataLog2Size()\n public\n pure\n override\n returns (uint256)\n {\n return VOUCHER_METADATA_LOG2_SIZE;\n }\n\n /// @notice get log2 size of epoch voucher memory range\n function getEpochVoucherLog2Size() public pure override returns (uint256) {\n return EPOCH_VOUCHER_LOG2_SIZE;\n }\n\n /// @notice get log2 size of notice metadata memory range\n function getNoticeMetadataLog2Size()\n public\n pure\n override\n returns (uint256)\n {\n return NOTICE_METADATA_LOG2_SIZE;\n }\n\n /// @notice get log2 size of epoch notice memory range\n function getEpochNoticeLog2Size() public pure override returns (uint256) {\n return EPOCH_NOTICE_LOG2_SIZE;\n }\n}\n" + }, + "@cartesi/util/contracts/Bitmask.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npragma solidity ^0.8.0;\n\n/// @title Bit Mask Library\n/// @author Stephen Chen\n/// @notice Implements bit mask with dynamic array\nlibrary Bitmask {\n /// @notice Set a bit in the bit mask\n function setBit(\n mapping(uint256 => uint256) storage bitmask,\n uint256 _bit,\n bool _value\n ) public {\n // calculate the number of bits has been store in bitmask now\n uint256 positionOfMask = uint256(_bit / 256);\n uint256 positionOfBit = _bit % 256;\n\n if (_value) {\n bitmask[positionOfMask] =\n bitmask[positionOfMask] |\n (1 << positionOfBit);\n } else {\n bitmask[positionOfMask] =\n bitmask[positionOfMask] &\n ~(1 << positionOfBit);\n }\n }\n\n /// @notice Get a bit in the bit mask\n function getBit(mapping(uint256 => uint256) storage bitmask, uint256 _bit)\n public\n view\n returns (bool)\n {\n // calculate the number of bits has been store in bitmask now\n uint256 positionOfMask = uint256(_bit / 256);\n uint256 positionOfBit = _bit % 256;\n\n return ((bitmask[positionOfMask] & (1 << positionOfBit)) != 0);\n }\n}\n" + }, + "@cartesi/util/contracts/Merkle.sol": { + "content": "// Copyright 2020 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Library for Merkle proofs\npragma solidity ^0.8.0;\n\nimport \"./CartesiMath.sol\";\n\nlibrary Merkle {\n using CartesiMath for uint256;\n\n uint128 constant L_WORD_SIZE = 3; // word = 8 bytes, log = 3\n // number of hashes in EMPTY_TREE_HASHES\n uint128 constant EMPTY_TREE_SIZE = 1952; // 61*32=1952. 32 bytes per 61 indexes (64 words)\n\n // merkle root hashes of trees of zero concatenated\n // 32 bytes for each root, first one is keccak(0), second one is\n // keccak(keccack(0), keccak(0)) and so on\n\n bytes constant EMPTY_TREE_HASHES =\n hex\"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce4d9470a821fbe90117ec357e30bad9305732fb19ddf54a07dd3e29f440619254ae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a233fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9c37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e68e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e30930b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90cd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efed8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0c9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e6163e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b72122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046f7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec517a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca892b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e152499af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f27d86025599a41233848702f0cfc0437b445682df51147a632a0a083d2d38b5e13e466a8935afff58bb533b3ef5d27fba63ee6b0fd9e67ff20af9d50deee3f8bf065ec220c1fd4ba57e341261d55997f85d66d32152526736872693d2b437a233e2337b715f6ac9a6a272622fdc2d67fcfe1da3459f8dab4ed7e40a657a54c36766c5e8ac9a88b35b05c34747e6507f6b044ab66180dc76ac1a696de03189593fedc0d0dbbd855c8ead673544899b0960e4a5a7ca43b4ef90afe607de7698caefdc242788f654b57a4fb32a71b335ef6ff9a4cc118b282b53bdd6d6192b7a82c3c5126b9c7e33c8e5a5ac9738b8bd31247fb7402054f97b573e8abb9faad219f4fd085aceaa7f542d787ee4196d365f3cc566e7bbcfbfd451230c48d804c017d21e2d8fa914e2559bb72bf0ab78c8ab92f00ef0d0d576eccdd486b64138a4172674857e543d1d5b639058dd908186597e366ad5f3d9c7ceaff44d04d1550b8d33abc751df07437834ba5acb32328a396994aebb3c40f759c2d6d7a3cb5377e55d5d218ef5a296dda8ddc355f3f50c3d0b660a51dfa4d98a6a5a33564556cf83c1373a814641d6a1dcef97b883fee61bb84fe60a3409340217e629cc7e4dcc93b85d8820921ff5826148b60e6939acd7838e1d7f20562bff8ee4b5ec4a05ad997a57b9796fdcb2eda87883c2640b072b140b946bfdf6575cacc066fdae04f6951e63624cbd316a677cad529bbe4e97b9144e4bc06c4afd1de55dd3e1175f90423847a230d34dfb71ed56f2965a7f6c72e6aa33c24c303fd67745d632656c5ef90bec80f4f5d1daa251988826cef375c81c36bf457e09687056f924677cb0bccf98dff81e014ce25f2d132497923e267363963cdf4302c5049d63131dc03fd95f65d8b6aa5934f817252c028c90f56d413b9d5d10d89790707dae2fabb249f649929927c21dd71e3f656826de5451c5da375aadecbd59d5ebf3a31fae65ac1b316a1611f1b276b26530f58d7247df459ce1f86db1d734f6f811932f042cee45d0e455306d01081bc3384f82c5fb2aacaa19d89cdfa46cc916eac61121475ba2e6191b4feecbe1789717021a158ace5d06744b40f551076b67cd63af60007f8c99876e1424883a45ec49d497ddaf808a5521ca74a999ab0b3c7aa9c80f85e93977ec61ce68b20307a1a81f71ca645b568fcd319ccbb5f651e87b707d37c39e15f945ea69e2f7c7d2ccc85b7e654c07e96f0636ae4044fe0e38590b431795ad0f8647bdd613713ada493cc17efd313206380e6a685b8198475bbd021c6e9d94daab2214947127506073e44d5408ba166c512a0b86805d07f5a44d3c41706be2bc15e712e55805248b92e8677d90f6d284d1d6ffaff2c430657042a0e82624fa3717b06cc0a6fd12230ea586dae83019fb9e06034ed2803c98d554b93c9a52348cafff75c40174a91f9ae6b8647854a156029f0b88b83316663ce574a4978277bb6bb27a31085634b6ec78864b6d8201c7e93903d75815067e378289a3d072ae172dafa6a452470f8d645bebfad9779594fc0784bb764a22e3a8181d93db7bf97893c414217a618ccb14caa9e92e8c61673afc9583662e812adba1f87a9c68202d60e909efab43c42c0cb00695fc7f1ffe67c75ca894c3c51e1e5e731360199e600f6ced9a87b2a6a87e70bf251bb5075ab222138288164b2eda727515ea7de12e2496d4fe42ea8d1a120c03cf9c50622c2afe4acb0dad98fd62d07ab4e828a94495f6d1ab973982c7ccbe6c1fae02788e4422ae22282fa49cbdb04ba54a7a238c6fc41187451383460762c06d1c8a72b9cd718866ad4b689e10c9a8c38fe5ef045bd785b01e980fc82c7e3532ce81876b778dd9f1ceeba4478e86411fb6fdd790683916ca832592485093644e8760cd7b4c01dba1ccc82b661bf13f0e3f34acd6b88\";\n\n /// @notice Gets merkle root hash of drive with a replacement\n /// @param _position position of _drive\n /// @param _logSizeOfReplacement log2 of size the replacement\n /// @param _logSizeOfFullDrive log2 of size the full drive, which can be the entire machine\n /// @param _replacement hash of the replacement\n /// @param siblings of replacement that merkle root can be calculated\n function getRootAfterReplacementInDrive(\n uint256 _position,\n uint256 _logSizeOfReplacement,\n uint256 _logSizeOfFullDrive,\n bytes32 _replacement,\n bytes32[] calldata siblings\n ) public pure returns (bytes32) {\n require(\n _logSizeOfFullDrive >= _logSizeOfReplacement &&\n _logSizeOfReplacement >= 3 &&\n _logSizeOfFullDrive <= 64,\n \"3 <= logSizeOfReplacement <= logSizeOfFullDrive <= 64\"\n );\n\n uint256 size = 1 << _logSizeOfReplacement;\n\n require(((size - 1) & _position) == 0, \"Position is not aligned\");\n require(\n siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement,\n \"Proof length does not match\"\n );\n\n for (uint256 i; i < siblings.length; i++) {\n if ((_position & (size << i)) == 0) {\n _replacement = keccak256(\n abi.encodePacked(_replacement, siblings[i])\n );\n } else {\n _replacement = keccak256(\n abi.encodePacked(siblings[i], _replacement)\n );\n }\n }\n\n return _replacement;\n }\n\n /// @notice Gets precomputed hash of zero in empty tree hashes\n /// @param _index of hash wanted\n /// @dev first index is keccak(0), second index is keccak(keccak(0), keccak(0))\n function getEmptyTreeHashAtIndex(uint256 _index)\n public\n pure\n returns (bytes32)\n {\n uint256 start = _index * 32;\n require(EMPTY_TREE_SIZE >= start + 32, \"index out of bounds\");\n bytes32 hashedZeros;\n bytes memory zeroTree = EMPTY_TREE_HASHES;\n\n // first word is length, then skip index words\n assembly {\n hashedZeros := mload(add(add(zeroTree, 0x20), start))\n }\n return hashedZeros;\n }\n\n /// @notice get merkle root of generic array of bytes\n /// @param _data array of bytes to be merklelized\n /// @param _log2Size log2 of total size of the drive\n /// @dev _data is padded with zeroes until is multiple of 8\n /// @dev root is completed with zero tree until log2size is complete\n /// @dev hashes are taken word by word (8 bytes by 8 bytes)\n function getMerkleRootFromBytes(bytes calldata _data, uint256 _log2Size)\n public\n pure\n returns (bytes32)\n {\n require(_log2Size >= 3 && _log2Size <= 64, \"range of log2Size: [3,64]\");\n\n // if _data is empty return pristine drive of size log2size\n if (_data.length == 0) return getEmptyTreeHashAtIndex(_log2Size - 3);\n\n // total size of the drive in words\n uint256 size = 1 << (_log2Size - 3);\n require(\n size << L_WORD_SIZE >= _data.length,\n \"data is bigger than drive\"\n );\n // the stack depth is log2(_data.length / 8) + 2\n uint256 stack_depth = 2 +\n ((_data.length) >> L_WORD_SIZE).getLog2Floor();\n bytes32[] memory stack = new bytes32[](stack_depth);\n\n uint256 numOfHashes; // total number of hashes on stack (counting levels)\n uint256 stackLength; // total length of stack\n uint256 numOfJoins; // number of hashes of the same level on stack\n uint256 topStackLevel; // hash level of the top of the stack\n\n while (numOfHashes < size) {\n if ((numOfHashes << L_WORD_SIZE) < _data.length) {\n // we still have words to hash\n stack[stackLength] = getHashOfWordAtIndex(_data, numOfHashes);\n numOfHashes++;\n\n numOfJoins = numOfHashes;\n } else {\n // since padding happens in hashOfWordAtIndex function\n // we only need to complete the stack with pre-computed\n // hash(0), hash(hash(0),hash(0)) and so on\n topStackLevel = numOfHashes.ctz();\n\n stack[stackLength] = getEmptyTreeHashAtIndex(topStackLevel);\n\n //Empty Tree Hash summarizes many hashes\n numOfHashes = numOfHashes + (1 << topStackLevel);\n numOfJoins = numOfHashes >> topStackLevel;\n }\n\n stackLength++;\n\n // while there are joins, hash top of stack together\n while (numOfJoins & 1 == 0) {\n bytes32 h2 = stack[stackLength - 1];\n bytes32 h1 = stack[stackLength - 2];\n\n stack[stackLength - 2] = keccak256(abi.encodePacked(h1, h2));\n stackLength = stackLength - 1; // remove hashes from stack\n\n numOfJoins = numOfJoins >> 1;\n }\n }\n require(stackLength == 1, \"stack error\");\n\n return stack[0];\n }\n\n /// @notice Get the hash of a word in an array of bytes\n /// @param _data array of bytes\n /// @param _wordIndex index of word inside the bytes to get the hash of\n /// @dev if word is incomplete (< 8 bytes) it gets padded with zeroes\n function getHashOfWordAtIndex(bytes calldata _data, uint256 _wordIndex)\n public\n pure\n returns (bytes32)\n {\n uint256 start = _wordIndex << L_WORD_SIZE;\n uint256 end = start + (1 << L_WORD_SIZE);\n\n // TODO: in .lua this just returns zero, but this might be more consistent\n require(start <= _data.length, \"word out of bounds\");\n\n if (end <= _data.length) {\n return keccak256(abi.encodePacked(_data[start:end]));\n }\n\n // word is incomplete\n // fill paddedSlice with incomplete words - the rest is going to be bytes(0)\n bytes memory paddedSlice = new bytes(8);\n uint256 remaining = _data.length - start;\n\n for (uint256 i; i < remaining; i++) {\n paddedSlice[i] = _data[start + i];\n }\n\n return keccak256(paddedSlice);\n }\n\n /// @notice Calculate the root of Merkle tree from an array of power of 2 elements\n /// @param hashes The array containing power of 2 elements\n /// @return byte32 the root hash being calculated\n function calculateRootFromPowerOfTwo(bytes32[] memory hashes)\n public\n pure\n returns (bytes32)\n {\n // revert when the input is not of power of 2\n require((hashes.length).isPowerOf2(), \"array len not power of 2\");\n\n if (hashes.length == 1) {\n return hashes[0];\n } else {\n bytes32[] memory newHashes = new bytes32[](hashes.length >> 1);\n\n for (uint256 i; i < hashes.length; i += 2) {\n newHashes[i >> 1] = keccak256(\n abi.encodePacked(hashes[i], hashes[i + 1])\n );\n }\n\n return calculateRootFromPowerOfTwo(newHashes);\n }\n }\n}\n" + }, + "contracts/interfaces/IOutput.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Output interface\npragma solidity >=0.7.0;\n\n/// @param epochIndex which epoch the output belongs to\n/// @param inputIndex which input, inside the epoch, the output belongs to\n/// @param outputIndex index of output inside the input\n/// @param outputHashesRootHash merkle root of all epoch's output metadata hashes\n/// @param vouchersEpochRootHash merkle root of all epoch's voucher metadata hashes\n/// @param noticesEpochRootHash merkle root of all epoch's notice metadata hashes\n/// @param machineStateHash hash of the machine state claimed this epoch\n/// @param keccakInHashesSiblings proof that this output metadata is in metadata memory range\n/// @param outputHashesInEpochSiblings proof that this output metadata is in epoch's output memory range\nstruct OutputValidityProof {\n uint256 epochIndex;\n uint256 inputIndex;\n uint256 outputIndex;\n bytes32 outputHashesRootHash;\n bytes32 vouchersEpochRootHash;\n bytes32 noticesEpochRootHash;\n bytes32 machineStateHash;\n bytes32[] keccakInHashesSiblings;\n bytes32[] outputHashesInEpochSiblings;\n}\n\ninterface IOutput {\n /// @notice executes voucher\n /// @param _destination address that will execute the payload\n /// @param _payload payload to be executed by destination\n /// @param _v validity proof for this encoded voucher\n /// @return true if voucher was executed successfully\n /// @dev vouchers can only be executed once\n function executeVoucher(\n address _destination,\n bytes calldata _payload,\n OutputValidityProof calldata _v\n ) external returns (bool);\n\n /// @notice get number of finalized epochs\n function getNumberOfFinalizedEpochs() external view returns (uint256);\n\n /// @notice get log2 size of voucher metadata memory range\n function getVoucherMetadataLog2Size() external pure returns (uint256);\n\n /// @notice get log2 size of epoch voucher memory range\n function getEpochVoucherLog2Size() external pure returns (uint256);\n\n /// @notice get log2 size of notice metadata memory range\n function getNoticeMetadataLog2Size() external pure returns (uint256);\n\n /// @notice get log2 size of epoch notice memory range\n function getEpochNoticeLog2Size() external pure returns (uint256);\n\n event VoucherExecuted(uint256 voucherPosition);\n}\n" + }, + "@cartesi/util/contracts/CartesiMath.sol": { + "content": "// Copyright 2020 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title CartesiMath\n/// @author Felipe Argento\npragma solidity ^0.8.0;\n\nlibrary CartesiMath {\n // mapping values are packed as bytes3 each\n // see test/TestCartesiMath.ts for decimal values\n bytes constant log2tableTimes1M =\n hex\"0000000F4240182F421E8480236E082771822AD63A2DC6C0305E8532B04834C96736B3C23876D73A187A3B9D4A3D09003E5EA63FA0C540D17741F28843057D440BA745062945F60246DC1047B917488DC7495ABA4A207C4ADF8A4B98544C4B404CF8AA4DA0E64E44434EE3054F7D6D5013B750A61A5134C851BFF05247BD52CC58534DE753CC8D54486954C19C55384255AC75561E50568DE956FB575766B057D00758376F589CFA5900BA5962BC59C3135A21CA5A7EF15ADA945B34BF5B8D805BE4DF5C3AEA5C8FA95CE3265D356C5D86835DD6735E25455E73005EBFAD5F0B525F55F75F9FA25FE85A60302460770860BD0A61023061467F6189FD61CCAE620E98624FBF62902762CFD5630ECD634D12638AA963C7966403DC643F7F647A8264B4E864EEB56527EC6560906598A365D029660724663D9766738566A8F066DDDA6712476746386779AF67ACAF67DF3A6811526842FA68743268A4FC68D55C6905536934E169640A6992CF69C13169EF326A1CD46A4A186A76FF6AA38C6ACFC0\";\n\n /// @notice Approximates log2 * 1M\n /// @param _num number to take log2 * 1M of\n /// @return approximate log2 times 1M\n function log2ApproxTimes1M(uint256 _num) public pure returns (uint256) {\n require(_num > 0, \"Number cannot be zero\");\n uint256 leading = 0;\n\n if (_num == 1) return 0;\n\n while (_num > 128) {\n _num = _num >> 1;\n leading += 1;\n }\n return (leading * uint256(1000000)) + (getLog2TableTimes1M(_num));\n }\n\n /// @notice navigates log2tableTimes1M\n /// @param _num number to take log2 of\n /// @return result after table look-up\n function getLog2TableTimes1M(uint256 _num) public pure returns (uint256) {\n bytes3 result = 0;\n for (uint8 i = 0; i < 3; i++) {\n bytes3 tempResult = log2tableTimes1M[(_num - 1) * 3 + i];\n result = result | (tempResult >> (i * 8));\n }\n\n return uint256(uint24(result));\n }\n\n /// @notice get floor of log2 of number\n /// @param _num number to take floor(log2) of\n /// @return floor(log2) of _num\n function getLog2Floor(uint256 _num) public pure returns (uint8) {\n require(_num != 0, \"log of zero is undefined\");\n\n return uint8(255 - clz(_num));\n }\n\n /// @notice checks if a number is Power of 2\n /// @param _num number to check\n /// @return true if number is power of 2, false if not\n function isPowerOf2(uint256 _num) public pure returns (bool) {\n if (_num == 0) return false;\n\n return _num & (_num - 1) == 0;\n }\n\n /// @notice count trailing zeros\n /// @param _num number you want the ctz of\n /// @dev this a binary search implementation\n function ctz(uint256 _num) public pure returns (uint256) {\n if (_num == 0) return 256;\n\n uint256 n = 0;\n if (_num & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { n = n + 128; _num = _num >> 128; }\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) { n = n + 64; _num = _num >> 64; }\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) { n = n + 32; _num = _num >> 32; }\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) { n = n + 16; _num = _num >> 16; }\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) { n = n + 8; _num = _num >> 8; }\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) { n = n + 4; _num = _num >> 4; }\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) { n = n + 2; _num = _num >> 2; }\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) { n = n + 1; }\n\n return n;\n }\n\n /// @notice count leading zeros\n /// @param _num number you want the clz of\n /// @dev this a binary search implementation\n function clz(uint256 _num) public pure returns (uint256) {\n if (_num == 0) return 256;\n\n uint256 n = 0;\n if (_num & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 == 0) { n = n + 128; _num = _num << 128; }\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) { n = n + 64; _num = _num << 64; }\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) { n = n + 32; _num = _num << 32; }\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 16; _num = _num << 16; }\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 8; _num = _num << 8; }\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 4; _num = _num << 4; }\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 2; _num = _num << 2; }\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) { n = n + 1; }\n\n return n;\n }\n}\n" + }, + "contracts/libraries/alternatives/LibValidatorManager1.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Validator Manager library (alternative version)\npragma solidity ^0.8.0;\n\nimport {Result} from \"../../interfaces/IValidatorManager.sol\";\n\n// TODO: this libray seems to be very unsafe, need to think about security implications\nlibrary LibValidatorManager1 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ValidatorManager.diamond.storage\");\n\n struct DiamondStorage {\n bytes32 currentClaim; // current claim - first claim of this epoch\n address payable[] validators; // current validators\n // A bit set for each validator that agrees with current claim,\n // on their respective positions\n uint32 claimAgreementMask;\n // Every validator who should approve (in order to reach consensus) will have a one set on this mask\n // This mask is updated if a validator is added or removed\n uint32 consensusGoalMask;\n }\n\n /// @notice emitted on Claim received\n event ClaimReceived(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on Dispute end\n event DisputeEnded(\n Result result,\n bytes32[2] claims,\n address payable[2] validators\n );\n\n /// @notice emitted on new Epoch\n event NewEpoch(bytes32 claim);\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n /// @notice called when a dispute ends in rollups\n /// @param ds diamond storage pointer\n /// @param winner address of dispute winner\n /// @param loser address of dispute loser\n /// @param winningClaim the winning claim\n /// @return result of dispute being finished\n function onDisputeEnd(\n DiamondStorage storage ds,\n address payable winner,\n address payable loser,\n bytes32 winningClaim\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n // remove validator also removes validator from both bitmask\n removeFromValidatorSetAndBothBitmasks(ds, loser);\n\n if (winningClaim == ds.currentClaim) {\n // first claim stood, dont need to update the bitmask\n return\n isConsensus(ds.claimAgreementMask, ds.consensusGoalMask)\n ? emitDisputeEndedAndReturn(\n Result.Consensus,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n )\n : emitDisputeEndedAndReturn(\n Result.NoConflict,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n );\n }\n\n // if first claim lost, and other validators have agreed with it\n // there is a new dispute to be played\n if (ds.claimAgreementMask != 0) {\n return\n emitDisputeEndedAndReturn(\n Result.Conflict,\n [ds.currentClaim, winningClaim],\n [getClaimerOfCurrentClaim(ds), winner]\n );\n }\n // else there are no valdiators that agree with losing claim\n // we can update current claim and check for consensus in case\n // the winner is the only validator left\n ds.currentClaim = winningClaim;\n ds.claimAgreementMask = updateClaimAgreementMask(ds, winner);\n return\n isConsensus(ds.claimAgreementMask, ds.consensusGoalMask)\n ? emitDisputeEndedAndReturn(\n Result.Consensus,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n )\n : emitDisputeEndedAndReturn(\n Result.NoConflict,\n [winningClaim, bytes32(0)],\n [winner, payable(0)]\n );\n }\n\n /// @notice called when a new epoch starts\n /// @param ds diamond storage pointer\n /// @return current claim\n function onNewEpoch(DiamondStorage storage ds) internal returns (bytes32) {\n bytes32 tmpClaim = ds.currentClaim;\n\n // clear current claim\n ds.currentClaim = bytes32(0);\n // clear validator agreement bit mask\n ds.claimAgreementMask = 0;\n\n emit NewEpoch(tmpClaim);\n return tmpClaim;\n }\n\n /// @notice called when a claim is received by rollups\n /// @param ds diamond storage pointer\n /// @param sender address of sender of that claim\n /// @param claim claim received by rollups\n /// @return result of claim, Consensus | NoConflict | Conflict\n /// @return [currentClaim, conflicting claim] if there is Conflict\n /// [currentClaim, bytes32(0)] if there is Consensus or NoConflcit\n /// @return [claimer1, claimer2] if there is Conflcit\n /// [claimer1, address(0)] if there is Consensus or NoConflcit\n function onClaim(\n DiamondStorage storage ds,\n address payable sender,\n bytes32 claim\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n require(claim != bytes32(0), \"empty claim\");\n require(isValidator(ds, sender), \"sender not allowed\");\n\n // cant return because a single claim might mean consensus\n if (ds.currentClaim == bytes32(0)) {\n ds.currentClaim = claim;\n }\n\n if (claim != ds.currentClaim) {\n return\n emitClaimReceivedAndReturn(\n Result.Conflict,\n [ds.currentClaim, claim],\n [getClaimerOfCurrentClaim(ds), sender]\n );\n }\n ds.claimAgreementMask = updateClaimAgreementMask(ds, sender);\n\n return\n isConsensus(ds.claimAgreementMask, ds.consensusGoalMask)\n ? emitClaimReceivedAndReturn(\n Result.Consensus,\n [claim, bytes32(0)],\n [sender, payable(0)]\n )\n : emitClaimReceivedAndReturn(\n Result.NoConflict,\n [claim, bytes32(0)],\n [sender, payable(0)]\n );\n }\n\n /// @notice emits dispute ended event and then return\n /// @param result to be emitted and returned\n /// @param claims to be emitted and returned\n /// @param validators to be emitted and returned\n /// @dev this function existis to make code more clear/concise\n function emitDisputeEndedAndReturn(\n Result result,\n bytes32[2] memory claims,\n address payable[2] memory validators\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n emit DisputeEnded(result, claims, validators);\n return (result, claims, validators);\n }\n\n /// @notice emits claim received event and then return\n /// @param result to be emitted and returned\n /// @param claims to be emitted and returned\n /// @param validators to be emitted and returned\n /// @dev this function existis to make code more clear/concise\n function emitClaimReceivedAndReturn(\n Result result,\n bytes32[2] memory claims,\n address payable[2] memory validators\n )\n internal\n returns (\n Result,\n bytes32[2] memory,\n address payable[2] memory\n )\n {\n emit ClaimReceived(result, claims, validators);\n return (result, claims, validators);\n }\n\n /// @notice get one of the validators that agreed with current claim\n /// @param ds diamond storage pointer\n /// @return validator that agreed with current claim\n function getClaimerOfCurrentClaim(DiamondStorage storage ds)\n internal\n view\n returns (address payable)\n {\n // TODO: we are always getting the first validator\n // on the array that agrees with the current claim to enter a dispute\n // should this be random?\n for (uint256 i; i < ds.validators.length; i++) {\n if (ds.claimAgreementMask & (1 << i) != 0) {\n return ds.validators[i];\n }\n }\n revert(\"Agreeing validator not found\");\n }\n\n /// @notice updates the consensus goal mask\n /// @param ds diamond storage pointer\n /// @return new consensus goal mask\n function updateConsensusGoalMask(DiamondStorage storage ds)\n internal\n view\n returns (uint32)\n {\n // consensus goal is a number where\n // all bits related to validators are turned on\n uint256 consensusMask = (1 << ds.validators.length) - 1;\n return uint32(consensusMask);\n }\n\n /// @notice updates mask of validators that agreed with current claim\n /// @param ds diamond storage pointer\n /// @param sender address that of validator that will be included in mask\n /// @return new claim agreement mask\n function updateClaimAgreementMask(\n DiamondStorage storage ds,\n address payable sender\n ) internal view returns (uint32) {\n uint256 tmpClaimAgreement = ds.claimAgreementMask;\n for (uint256 i; i < ds.validators.length; i++) {\n if (sender == ds.validators[i]) {\n tmpClaimAgreement = (tmpClaimAgreement | (1 << i));\n break;\n }\n }\n\n return uint32(tmpClaimAgreement);\n }\n\n /// @notice removes a validator\n /// @param ds diamond storage pointer\n /// @param validator address of validator to be removed\n function removeFromValidatorSetAndBothBitmasks(\n DiamondStorage storage ds,\n address validator\n ) internal {\n // put address(0) in validators position\n // removes validator from claim agreement bitmask\n // removes validator from consensus goal mask\n for (uint256 i; i < ds.validators.length; i++) {\n if (validator == ds.validators[i]) {\n ds.validators[i] = payable(0);\n uint32 zeroMask = ~(uint32(1) << uint32(i));\n ds.claimAgreementMask = ds.claimAgreementMask & zeroMask;\n ds.consensusGoalMask = ds.consensusGoalMask & zeroMask;\n break;\n }\n }\n }\n\n function isValidator(DiamondStorage storage ds, address sender)\n internal\n view\n returns (bool)\n {\n for (uint256 i; i < ds.validators.length; i++) {\n if (sender == ds.validators[i]) return true;\n }\n\n return false;\n }\n\n function isConsensus(uint256 claimAgreementMask, uint256 consensusGoalMask)\n internal\n pure\n returns (bool)\n {\n return claimAgreementMask == consensusGoalMask;\n }\n}\n" + }, + "contracts/facets/alternatives/ValidatorManagerFacet1.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Validator Manager facet (alternative version)\npragma solidity ^0.8.0;\n\nimport {IValidatorManager} from \"../../interfaces/IValidatorManager.sol\";\n\nimport {LibValidatorManager1} from \"../../libraries/alternatives/LibValidatorManager1.sol\";\n\ncontract ValidatorManagerFacet1 is IValidatorManager {\n /// @notice get agreement mask\n /// @return current state of agreement mask\n function getCurrentAgreementMask() public view returns (uint32) {\n LibValidatorManager1.DiamondStorage\n storage validatorManagerDS = LibValidatorManager1.diamondStorage();\n return validatorManagerDS.claimAgreementMask;\n }\n\n /// @notice get consensus goal mask\n /// @return current consensus goal mask\n function getConsensusGoalMask() public view returns (uint32) {\n LibValidatorManager1.DiamondStorage\n storage validatorManagerDS = LibValidatorManager1.diamondStorage();\n return validatorManagerDS.consensusGoalMask;\n }\n\n /// @notice get current claim\n /// @return current claim\n function getCurrentClaim() public view override returns (bytes32) {\n LibValidatorManager1.DiamondStorage\n storage validatorManagerDS = LibValidatorManager1.diamondStorage();\n return validatorManagerDS.currentClaim;\n }\n}\n" + }, + "contracts/upgrade_initializers/DiamondInit.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n// @title Diamond Initialization Contract\npragma solidity ^0.8.0;\n\n// Rollups-related dependencies\nimport {Phase} from \"../interfaces/IRollups.sol\";\nimport {LibRollups} from \"../libraries/LibRollups.sol\";\nimport {LibInput} from \"../libraries/LibInput.sol\";\nimport {LibValidatorManager} from \"../libraries/LibValidatorManager.sol\";\nimport {LibClaimsMask} from \"../libraries/LibClaimsMask.sol\";\nimport {LibFeeManager} from \"../libraries/LibFeeManager.sol\";\nimport {IBank} from \"../IBank.sol\";\n\n// Diamond-related dependencies\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {IDiamondLoupe} from \"../interfaces/IDiamondLoupe.sol\";\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\nimport {IERC173} from \"../interfaces/IERC173.sol\"; // not in openzeppelin-contracts yet\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/// @notice diamond configurations\n/// @param templateHash state hash of the cartesi machine at t0\n/// @param inputDuration duration of input accumulation phase in seconds\n/// @param challengePeriod duration of challenge period in seconds\n/// @param inputLog2Size size of the input memory range in this machine\n/// @param feePerClaim fee per claim to reward the validators\n/// @param feeManagerBank fee manager bank address\n/// @param feeManagerOwner fee manager owner address\n/// @param validators initial validator set\n/// @dev validators have to be unique, if the same validator is added twice\n/// consensus will never be reached\nstruct DiamondConfig {\n // RollupsFacet\n bytes32 templateHash;\n uint256 inputDuration;\n uint256 challengePeriod;\n // InputFacet\n uint256 inputLog2Size;\n // FeeManagerFacet\n uint256 feePerClaim;\n address feeManagerBank;\n address feeManagerOwner;\n // ValidatorManagerFacet\n address payable[] validators;\n}\n\ncontract DiamondInit {\n using LibValidatorManager for LibValidatorManager.DiamondStorage;\n using LibInput for LibInput.DiamondStorage;\n\n /// @notice initialize the diamond\n /// @param _dConfig diamond configurations\n function init(DiamondConfig calldata _dConfig) external {\n initERC165();\n initValidatorManager(_dConfig.validators);\n initRollups(\n _dConfig.templateHash,\n _dConfig.inputDuration,\n _dConfig.challengePeriod\n );\n initFeeManager(\n _dConfig.feePerClaim,\n _dConfig.feeManagerBank,\n _dConfig.feeManagerOwner\n );\n initInput(_dConfig.inputLog2Size);\n }\n\n /// @notice initialize ERC165 data\n function initERC165() private {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n ds.supportedInterfaces[type(IERC165).interfaceId] = true;\n ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;\n ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;\n ds.supportedInterfaces[type(IERC173).interfaceId] = true;\n }\n\n /// @notice initalize the Input facet\n /// @param _inputLog2Size size of the input memory range in this machine\n function initInput(uint256 _inputLog2Size) private {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n\n require(\n _inputLog2Size >= 3 && _inputLog2Size <= 64,\n \"Log of input size: [3,64]\"\n );\n\n inputDS.inputDriveSize = (1 << _inputLog2Size);\n\n // input box gets initialized with one empty input\n // so that the L2 DApp knows it's own address\n inputDS.addInternalInput(\"\");\n }\n\n /// @notice initialize the Validator Manager facet\n /// @param _validators initial validator set\n function initValidatorManager(address payable[] memory _validators)\n private\n {\n LibValidatorManager.DiamondStorage\n storage validatorManagerDS = LibValidatorManager.diamondStorage();\n\n uint256 maxNumValidators = _validators.length;\n\n require(maxNumValidators <= 8, \"up to 8 validators\");\n\n validatorManagerDS.validators = _validators;\n validatorManagerDS.maxNumValidators = maxNumValidators;\n\n // create a new ClaimsMask, with only the consensus goal set,\n // according to the number of validators\n validatorManagerDS.claimsMask = LibClaimsMask\n .newClaimsMaskWithConsensusGoalSet(maxNumValidators);\n }\n\n /// @notice rollups contract initialized\n /// @param inputDuration duration of input accumulation phase in seconds\n /// @param challengePeriod duration of challenge period in seconds\n event RollupsInitialized(uint256 inputDuration, uint256 challengePeriod);\n\n /// @notice initialize the Rollups facet\n /// @param _templateHash state hash of the cartesi machine at t0\n /// @param _inputDuration duration of input accumulation phase in seconds\n /// @param _challengePeriod duration of challenge period in seconds\n function initRollups(\n bytes32 _templateHash,\n uint256 _inputDuration,\n uint256 _challengePeriod\n ) private {\n LibRollups.DiamondStorage storage rollupsDS = LibRollups\n .diamondStorage();\n\n rollupsDS.templateHash = _templateHash;\n rollupsDS.inputDuration = uint32(_inputDuration);\n rollupsDS.challengePeriod = uint32(_challengePeriod);\n rollupsDS.inputAccumulationStart = uint32(block.timestamp);\n rollupsDS.currentPhase_int = uint32(Phase.InputAccumulation);\n\n emit RollupsInitialized(_inputDuration, _challengePeriod);\n }\n\n /// @notice FeeManagerImpl contract initialized\n /// @param feePerClaim fee per claim to reward the validators\n /// @param feeManagerBank fee manager bank address\n /// @param feeManagerOwner fee manager owner address\n event FeeManagerInitialized(\n uint256 feePerClaim,\n address feeManagerBank,\n address feeManagerOwner\n );\n\n /// @notice initalize the Fee Manager facet\n /// @param _feePerClaim fee per claim to reward the validators\n /// @param _feeManagerBank fee manager bank address\n /// @param _feeManagerOwner fee manager owner address\n function initFeeManager(\n uint256 _feePerClaim,\n address _feeManagerBank,\n address _feeManagerOwner\n ) private {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n\n feeManagerDS.feePerClaim = _feePerClaim;\n feeManagerDS.bank = IBank(_feeManagerBank);\n feeManagerDS.owner = _feeManagerOwner;\n\n emit FeeManagerInitialized(\n _feePerClaim,\n _feeManagerBank,\n _feeManagerOwner\n );\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"diamond.standard.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // owner of the contract\n address contractOwner;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(\n msg.sender == diamondStorage().contractOwner,\n \"LibDiamond: Must be contract owner\"\n );\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] diamondCut,\n address init,\n bytes callData\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < _selectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < _selectors.length;\n selectorIndex++\n ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (\n uint256 selectorIndex;\n selectorIndex < _selectors.length;\n selectorIndex++\n ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata)\n internal\n {\n if (_init == address(0)) {\n require(\n _calldata.length == 0,\n \"LibDiamondCut: _init is address(0) but_calldata is not empty\"\n );\n } else {\n require(\n _calldata.length > 0,\n \"LibDiamondCut: _calldata is empty but _init is not address(0)\"\n );\n if (_init != address(this)) {\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n }\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up the error\n revert(string(error));\n } else {\n revert(\"LibDiamondCut: _init function reverted\");\n }\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(address _facet)\n external\n view\n returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector)\n external\n view\n returns (address facetAddress_);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] diamondCut, address init, bytes callData);\n}\n" + }, + "contracts/interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {IERC173} from \"../interfaces/IERC173.sol\";\n\ncontract OwnershipFacet is IERC173 {\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.setContractOwner(_newOwner);\n }\n\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n}\n" + }, + "contracts/facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {IDiamondLoupe} from \"../interfaces/IDiamondLoupe.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract DiamondLoupeFacet is IDiamondLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new Facet[](ds.selectorCount);\n uint8[] memory numFacetSelectors = new uint8[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_ The selectors associated with a facet address.\n function facetFunctionSelectors(address _facet)\n external\n view\n override\n returns (bytes4[] memory facetFunctionSelectors_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n facetFunctionSelectors_ = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n facetFunctionSelectors_[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(facetFunctionSelectors_, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector)\n external\n view\n override\n returns (address facetAddress_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n }\n\n // This implements ERC-165.\n function supportsInterface(bytes4 _interfaceId)\n external\n view\n override\n returns (bool)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n return ds.supportedInterfaces[_interfaceId];\n }\n}\n" + }, + "contracts/facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\n\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorCount >> 3\" is a gas efficient division by 8 \"selectorCount / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n (selectorCount, selectorSlot) = LibDiamond\n .addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorCount >> 3\" is a gas efficient division by 8 \"selectorCount / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n LibDiamond.initializeDiamondCut(_init, _calldata);\n }\n}\n" + }, + "contracts/CartesiDAppFactory.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n// @title Cartesi DApp Factory\npragma solidity ^0.8.0;\n\nimport {ICartesiDAppFactory} from \"./ICartesiDAppFactory.sol\";\nimport {CartesiDApp} from \"./CartesiDApp.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\nimport {IERC173} from \"./interfaces/IERC173.sol\";\nimport {DiamondInit, DiamondConfig} from \"./upgrade_initializers/DiamondInit.sol\";\nimport {IBank} from \"./IBank.sol\";\n\ncontract CartesiDAppFactory is ICartesiDAppFactory {\n IDiamondCut public immutable diamondCutFacet;\n DiamondInit public immutable diamondInit;\n IBank public immutable feeManagerBank;\n IDiamondCut.FacetCut[] public diamondCut;\n\n struct FactoryConfig {\n IDiamondCut diamondCutFacet;\n DiamondInit diamondInit;\n IBank feeManagerBank;\n IDiamondCut.FacetCut[] diamondCut;\n }\n\n constructor(FactoryConfig memory _fConfig) {\n diamondCutFacet = _fConfig.diamondCutFacet;\n diamondInit = _fConfig.diamondInit;\n feeManagerBank = _fConfig.feeManagerBank;\n for (uint256 i; i < _fConfig.diamondCut.length; ++i) {\n diamondCut.push(_fConfig.diamondCut[i]);\n }\n }\n\n function newApplication(AppConfig calldata _appConfig)\n public\n returns (CartesiDApp)\n {\n CartesiDApp application = new CartesiDApp(\n address(this),\n address(diamondCutFacet)\n );\n DiamondConfig memory dConfig = DiamondConfig({\n templateHash: _appConfig.templateHash,\n inputDuration: _appConfig.inputDuration,\n challengePeriod: _appConfig.challengePeriod,\n inputLog2Size: _appConfig.inputLog2Size,\n feePerClaim: _appConfig.feePerClaim,\n feeManagerBank: address(feeManagerBank),\n feeManagerOwner: _appConfig.feeManagerOwner,\n validators: _appConfig.validators\n });\n IDiamondCut(address(application)).diamondCut(\n diamondCut,\n address(diamondInit),\n abi.encodeWithSelector(DiamondInit.init.selector, dConfig)\n );\n IERC173(address(application)).transferOwnership(\n _appConfig.diamondOwner\n );\n emit ApplicationCreated(application, _appConfig);\n return application;\n }\n}\n" + }, + "contracts/ICartesiDAppFactory.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n// @title Cartesi DApp Factory interface\npragma solidity ^0.8.0;\n\nimport {CartesiDApp} from \"./CartesiDApp.sol\";\n\ninterface ICartesiDAppFactory {\n /// @notice application configurations\n /// @param diamondOwner diamond owner\n /// @param templateHash state hash of the cartesi machine at t0\n /// @param inputDuration duration of input accumulation phase in seconds\n /// @param challengePeriod duration of challenge period in seconds\n /// @param inputLog2Size size of the input memory range in this machine\n /// @param feePerClaim fee per claim to reward the validators\n /// @param feeManagerOwner fee manager owner address\n /// @param validators initial validator set\n /// @dev validators have to be unique, if the same validator is added twice\n /// consensus will never be reached\n struct AppConfig {\n // DiamondCutFacet\n address diamondOwner;\n // RollupsFacet\n bytes32 templateHash;\n uint256 inputDuration;\n uint256 challengePeriod;\n // InputFacet\n uint256 inputLog2Size;\n // FeeManagerFacet\n uint256 feePerClaim;\n address feeManagerOwner;\n // ValidatorManagerFacet\n address payable[] validators;\n }\n\n /// @notice Deploy a new application\n /// @param _appConfig application configurations\n /// @return application address\n function newApplication(AppConfig calldata _appConfig)\n external\n returns (CartesiDApp);\n\n /// @notice Event emitted when a new application is deployed\n /// @param application application address\n /// @param config application configurations\n event ApplicationCreated(CartesiDApp indexed application, AppConfig config);\n}\n" + }, + "contracts/CartesiDApp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\ncontract CartesiDApp {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n require(facet != address(0), \"Diamond: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/interfaces/IFeeManager.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Fee Manager interface\npragma solidity >=0.7.0;\n\nimport {IBank} from \"../IBank.sol\";\n\ninterface IFeeManager {\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\n /// @param _validator address of the validator\n function numClaimsRedeemable(address _validator)\n external\n view\n returns (uint256);\n\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\n /// @param _validator address of the validator\n function getNumClaimsRedeemed(address _validator)\n external\n view\n returns (uint256);\n\n /// @notice contract owner can set/reset the value of fee per claim\n /// @param _value the new value of fee per claim\n function resetFeePerClaim(uint256 _value) external;\n\n /// @notice this function can be called to redeem fees for validators\n /// @param _validator address of the validator that is redeeming\n function redeemFee(address _validator) external;\n\n /// @notice returns the bank used to manage fees\n function getFeeManagerBank() external view returns (IBank);\n\n /// @notice emitted on resetting feePerClaim\n event FeePerClaimReset(uint256 value);\n\n /// @notice emitted on ERC20 funds redeemed by validator\n event FeeRedeemed(address validator, uint256 claims);\n}\n" + }, + "contracts/facets/FeeManagerFacet.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Fee Manager facet\npragma solidity >=0.8.8;\n\nimport {IBank} from \"../IBank.sol\";\nimport {IFeeManager} from \"../interfaces/IFeeManager.sol\";\nimport {LibFeeManager} from \"../libraries/LibFeeManager.sol\";\n\ncontract FeeManagerFacet is IFeeManager {\n using LibFeeManager for LibFeeManager.DiamondStorage;\n\n /// @notice functions modified by noReentrancy are not subject to recursion\n modifier noReentrancy() {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n require(!feeManagerDS.lock, \"reentrancy not allowed\");\n feeManagerDS.lock = true;\n _;\n feeManagerDS.lock = false;\n }\n\n /// @notice this function can be called to check the number of claims that's redeemable for the validator\n /// @param _validator address of the validator\n function numClaimsRedeemable(address _validator)\n public\n view\n override\n returns (uint256)\n {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n return feeManagerDS.numClaimsRedeemable(_validator);\n }\n\n /// @notice this function can be called to check the number of claims that has been redeemed for the validator\n /// @param _validator address of the validator\n function getNumClaimsRedeemed(address _validator)\n public\n view\n override\n returns (uint256)\n {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n return feeManagerDS.getNumClaimsRedeemed(_validator);\n }\n\n /// @notice contract owner can reset the value of fee per claim\n /// @param _value the new value of fee per claim\n function resetFeePerClaim(uint256 _value) public override {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n feeManagerDS.onlyOwner();\n feeManagerDS.resetFeePerClaim(_value);\n }\n\n /// @notice this function can be called to redeem fees for validators\n /// @param _validator address of the validator that is redeeming\n function redeemFee(address _validator) public override noReentrancy {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n feeManagerDS.redeemFee(_validator);\n }\n\n /// @notice returns the bank used to manage fees\n function getFeeManagerBank() public view override returns (IBank) {\n LibFeeManager.DiamondStorage storage feeManagerDS = LibFeeManager\n .diamondStorage();\n return feeManagerDS.bank;\n }\n}\n" + }, + "contracts/facets/ERC20PortalFacet.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Generic ERC20 Portal facet\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {IERC20Portal} from \"../interfaces/IERC20Portal.sol\";\n\nimport {LibInput} from \"../libraries/LibInput.sol\";\n\ncontract ERC20PortalFacet is IERC20Portal {\n using LibInput for LibInput.DiamondStorage;\n\n bytes32 constant INPUT_HEADER = keccak256(\"ERC20_Transfer\");\n\n /// @notice deposit an amount of a generic ERC20 in the portal and create tokens in L2\n /// @param _ERC20 address of the ERC20 token contract\n /// @param _amount amount of the ERC20 token to be deposited\n /// @param _data information to be interpreted by L2\n /// @return hash of input generated by deposit\n function erc20Deposit(\n address _ERC20,\n uint256 _amount,\n bytes calldata _data\n ) public override returns (bytes32) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n IERC20 token = IERC20(_ERC20);\n\n require(\n token.transferFrom(msg.sender, address(this), _amount),\n \"ERC20 transferFrom failed\"\n );\n\n bytes memory input = abi.encode(\n INPUT_HEADER,\n msg.sender,\n _ERC20,\n _amount,\n _data\n );\n\n emit ERC20Deposited(_ERC20, msg.sender, _amount, _data);\n return inputDS.addInternalInput(input);\n }\n}\n" + }, + "contracts/facets/EtherPortalFacet.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Ether Portal facet\npragma solidity ^0.8.0;\n\nimport {IEtherPortal} from \"../interfaces/IEtherPortal.sol\";\n\nimport {LibInput} from \"../libraries/LibInput.sol\";\n\ncontract EtherPortalFacet is IEtherPortal {\n using LibInput for LibInput.DiamondStorage;\n\n bytes32 constant INPUT_HEADER = keccak256(\"Ether_Transfer\");\n\n /// @notice deposit an amount of Ether in the portal and create Ether in L2\n /// @param _data information to be interpreted by L2\n /// @return hash of input generated by deposit\n function etherDeposit(bytes calldata _data)\n public\n payable\n override\n returns (bytes32)\n {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n bytes memory input = abi.encode(\n INPUT_HEADER,\n msg.sender,\n msg.value,\n _data\n );\n\n emit EtherDeposited(msg.sender, msg.value, _data);\n return inputDS.addInternalInput(input);\n }\n\n /// @notice withdraw an amount of Ether from the portal\n /// @param _data data with withdrawal information\n /// @dev can only be called by the Rollups contract\n function etherWithdrawal(bytes calldata _data)\n public\n override\n returns (bool)\n {\n // Delegate calls preserve msg.sender, msg.value and address(this)\n require(msg.sender == address(this), \"only itself\");\n\n (address payable receiver, uint256 value) = abi.decode(\n _data,\n (address, uint256)\n );\n\n // We used to call receiver.transfer(value) but it's no\n // longer considered safe, as it assumes gas costs are\n // immutable, while in fact they are not.\n (bool success, ) = receiver.call{value: value}(\"\");\n require(success, \"transfer failed\");\n\n emit EtherWithdrawn(receiver, value);\n\n return true;\n }\n}\n" + }, + "contracts/facets/InputFacet.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Input facet\npragma solidity ^0.8.0;\n\nimport {IInput} from \"../interfaces/IInput.sol\";\n\nimport {LibInput} from \"../libraries/LibInput.sol\";\n\ncontract InputFacet is IInput {\n using LibInput for LibInput.DiamondStorage;\n\n /// @notice add input to processed by next epoch\n /// @param _input input to be understood by offchain machine\n /// @dev offchain code is responsible for making sure\n /// that input size is power of 2 and multiple of 8 since\n // the offchain machine has a 8 byte word\n function addInput(bytes calldata _input) public override returns (bytes32) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n return inputDS.addInput(_input);\n }\n\n /// @notice get input inside inbox of currently proposed claim\n /// @param _index index of input inside that inbox\n /// @return hash of input at index _index\n /// @dev currentInputBox being zero means that the inputs for\n /// the claimed epoch are on input box one\n function getInput(uint256 _index) public view override returns (bytes32) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n return inputDS.getInput(_index);\n }\n\n /// @notice get number of inputs inside inbox of currently proposed claim\n /// @return number of inputs on that input box\n /// @dev currentInputBox being zero means that the inputs for\n /// the claimed epoch are on input box one\n function getNumberOfInputs() public view override returns (uint256) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n return inputDS.getNumberOfInputs();\n }\n\n /// @notice get inbox currently receiveing inputs\n /// @return input inbox currently receiveing inputs\n function getCurrentInbox() public view override returns (uint256) {\n LibInput.DiamondStorage storage inputDS = LibInput.diamondStorage();\n return inputDS.currentInputBox;\n }\n}\n" + }, + "contracts/interfaces/IInput.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title Input interface\npragma solidity >=0.7.0;\n\ninterface IInput {\n /// @notice adds input to correct inbox\n /// @param _input bytes array of input\n /// @return merkle root hash of input\n /// @dev msg.sender and timestamp are preppended log2 size\n /// has to be calculated offchain taking that into account\n function addInput(bytes calldata _input) external returns (bytes32);\n\n /// @notice returns input from correct input inbox\n /// @param _index position of the input on inbox\n /// @return root hash of input\n function getInput(uint256 _index) external view returns (bytes32);\n\n /// @notice returns number of inputs on correct inbox\n /// @return number of inputs of non active inbox\n function getNumberOfInputs() external view returns (uint256);\n\n /// @notice returns active current inbox index\n /// @return index of current active inbox\n function getCurrentInbox() external view returns (uint256);\n\n /// @notice input added\n /// @param epochNumber which epoch this input belongs to\n /// @param inputIndex index of the input just added\n /// @param sender msg.sender\n /// @param timestamp block.timestamp\n /// @param input input data\n event InputAdded(\n uint256 indexed epochNumber,\n uint256 indexed inputIndex,\n address sender,\n uint256 timestamp,\n bytes input\n );\n}\n" + }, + "contracts/test_helper/SimpleNFT.sol": { + "content": "// Copyright 2022 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title A Simple NFT Contract\npragma solidity ^0.8.0;\n\nimport {ERC721} from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract SimpleNFT is ERC721 {\n // name: SimpleNFT\n // symbol: SIM\n constructor(uint256[] memory tokenIds) ERC721(\"SimpleNFT\", \"SIM\") {\n for (uint256 i; i < tokenIds.length; i++) {\n _safeMint(msg.sender, tokenIds[i]);\n }\n }\n}\n" + }, + "contracts/test_helper/SimpleToken.sol": { + "content": "// Copyright 2021 Cartesi Pte. Ltd.\n\n// SPDX-License-Identifier: Apache-2.0\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n// this file except in compliance with the License. You may obtain a copy of the\n// License at http://www.apache.org/licenses/LICENSE-2.0\n\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n/// @title A Simple Token\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract SimpleToken is ERC20 {\n // name: SimpleToken\n // symbol: SIM\n constructor(uint256 initialSupply) ERC20(\"SimpleToken\", \"SIM\") {\n // on Hardhat network, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 should be the address of signers[0]\n // generated from default mnemonic \"test test test test test test test test test test test junk\"\n _mint(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, initialSupply);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/echo-js/docker-bake.hcl b/echo-js/docker-bake.hcl new file mode 100644 index 00000000..285e8a62 --- /dev/null +++ b/echo-js/docker-bake.hcl @@ -0,0 +1,43 @@ + +group "default" { + targets = ["dapp", "server", "console"] +} + +# crossenv toolchain for js dapps +target "toolchain-js" { + context = "./docker" + target = "toolchain-js" + tags = ["cartesi/toolchain-js"] +} + +target "fs" { + context = "./docker" + target = "dapp-fs-build" + contexts = { + dapp-build = "target:dapp" + } +} + +target "server" { + context = "./docker" + target = "machine-server" + contexts = { + dapp-build = "target:dapp" + } +} + +target "console" { + context = "./docker" + target = "machine-console" + contexts = { + dapp-build = "target:dapp" + } +} + +target "machine" { + context = "./docker" + target = "machine-standalone" + contexts = { + dapp-build = "target:dapp" + } +} diff --git a/echo-js/docker-bake.override.hcl b/echo-js/docker-bake.override.hcl new file mode 100644 index 00000000..347bc1d3 --- /dev/null +++ b/echo-js/docker-bake.override.hcl @@ -0,0 +1,15 @@ + +target "dapp" { +} + +target "server" { + tags = ["cartesi/dapp:echo-js-devel-server"] +} + +target "console" { + tags = ["cartesi/dapp:echo-js-devel-console"] +} + +target "machine" { + tags = ["cartesi/dapp:echo-js-devel-machine"] +} diff --git a/echo-js/docker-compose.override.yml b/echo-js/docker-compose.override.yml new file mode 100644 index 00000000..2f21a433 --- /dev/null +++ b/echo-js/docker-compose.override.yml @@ -0,0 +1,5 @@ +version: "3" + +services: + server_manager: + image: cartesi/dapp:echo-js-devel-server diff --git a/echo-js/docker/Dockerfile b/echo-js/docker/Dockerfile new file mode 100644 index 00000000..80584c23 --- /dev/null +++ b/echo-js/docker/Dockerfile @@ -0,0 +1,134 @@ +# syntax=docker.io/docker/dockerfile:1.4 +# layers for caching and versioning +FROM cartesi/toolchain:0.10.0 as toolchain +FROM cartesi/rootfs:0.12.0 as rootfs +FROM cartesi/server-manager:0.3.0 as server-manager + +FROM rootfs as toolchain-js + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt update \ + && apt install -y \ + libncurses-dev \ + libgdbm-dev \ + libz-dev \ + tk-dev \ + libsqlite3-dev \ + libreadline-dev \ + liblzma-dev \ + libffi-dev \ + libssl-dev + +ENV PYTHON_VERSION=3.10 +ENV PYTHON_VERSION_FULL=3.10.1 +ENV BUILD_PYTHON_PREFIX=/opt/build-python +ENV HOST_PYTHON_PREFIX=/mnt/python-dapp + +# Download Python source +WORKDIR /tmp +RUN wget https://www.python.org/ftp/python/$PYTHON_VERSION_FULL/Python-$PYTHON_VERSION_FULL.tgz +RUN tar zxfv Python-$PYTHON_VERSION_FULL.tgz + +# Build build-python from source +RUN cp -r Python-$PYTHON_VERSION_FULL build-python +WORKDIR /tmp/build-python +RUN ./configure --prefix=$BUILD_PYTHON_PREFIX +RUN make -j$(nproc) +RUN make install + +ENV PATH=$BUILD_PYTHON_PREFIX/bin:$PATH + +# Build host-python +WORKDIR /tmp +RUN cp -r Python-$PYTHON_VERSION_FULL host-python +WORKDIR /tmp/host-python +RUN CPPFLAGS="-I/opt/riscv/rootfs/buildroot/work/staging/usr/include" \ + LDFLAGS="-L/opt/riscv/rootfs/buildroot/work/staging/usr/lib" \ + ./configure \ + --enable-shared \ + --enable-optimizations \ + --prefix=$HOST_PYTHON_PREFIX \ + --host=riscv64-cartesi-linux-gnu \ + --build=x86_64-linux-gnu \ + --without-ensurepip \ + --disable-test-modules \ + ac_cv_buggy_getaddrinfo=no \ + ac_cv_file__dev_ptmx=yes \ + ac_cv_file__dev_ptc=no +WORKDIR /tmp/host-python +RUN make -j$(nproc) +RUN make install + +WORKDIR /tmp +RUN pip3 install crossenv +RUN rm -rf Python-$PYTHON_VERSION_FULL* + +# download standard machine drives +FROM busybox as machine-core + +WORKDIR /opt/cartesi/share + +# download dependencies +COPY dependencies . +COPY shasumfile . +RUN cat dependencies | xargs wget +RUN sha1sum -c shasumfile + +# stage to build the dapp ext2 filesystem +FROM toolchain as dapp-fs-build + +# install jq +RUN < $FILES +rsync -r --files-from=$FILES . $FS_DIR + +# create tar +tar --sort=name --mtime="2022-01-01" --owner=0 --group=0 --numeric-owner -cf $TAR --directory=$FS_DIR . + +# generate ext2 filesystem +FS_SIZE=$(jq -rs '.[0] * .[1] | .fs.size // 4096' $CONFIG_DEFAULT $CONFIG_DAPP) +genext2fs -f -i 512 -b $FS_SIZE -a $TAR $EXT2 + +# truncate to multiple of 4k +truncate -s %4096 $EXT2 diff --git a/echo-js/docker/build-machine.sh b/echo-js/docker/build-machine.sh new file mode 100755 index 00000000..3a205ab9 --- /dev/null +++ b/echo-js/docker/build-machine.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +set -e + +MACHINE_DIR=$1 +ROLLUP_HTTP_SERVER_PORT=5004 + +cartesi-machine \ + --ram-length=128Mi \ + --rollup \ + --flash-drive=label:dapp,filename:dapp.ext2 \ + --flash-drive=label:root,filename:rootfs.ext2 \ + --ram-image=linux-5.5.19-ctsi-5.bin \ + --rom-image=rom.bin \ + --store=$MACHINE_DIR \ + -- "cd /mnt/dapp; \ + ROLLUP_HTTP_SERVER_URL=\"http://127.0.0.1:$ROLLUP_HTTP_SERVER_PORT\" \ + ./entrypoint.sh" diff --git a/echo-js/docker/default.json b/echo-js/docker/default.json new file mode 100644 index 00000000..6b5013ba --- /dev/null +++ b/echo-js/docker/default.json @@ -0,0 +1,17 @@ +{ + "fs": { + "files": ["entrypoint.sh"], + "size": 4096 + }, + "machine": { + "entrypoint": "entrypoint.sh", + "ramLength": "128Mi" + }, + "contract": { + "inputDuration": 86400, + "challengePeriod": 604800, + "inputLog2Size": 25, + "feePerClaim": "1000000000000000000", + "validators": "0,1,2" + } +} diff --git a/echo-js/docker/dependencies b/echo-js/docker/dependencies new file mode 100644 index 00000000..b0ba67a2 --- /dev/null +++ b/echo-js/docker/dependencies @@ -0,0 +1,3 @@ +https://wchfs-media.fra1.digitaloceanspaces.com/cartesi/fs/example-js/0.12.0/rootfs.ext2 +https://github.com/cartesi/image-kernel/releases/download/v0.12.0/linux-5.5.19-ctsi-5.bin +https://github.com/cartesi/machine-emulator-rom/releases/download/v0.11.0/rom.bin diff --git a/echo-js/docker/run-machine-console.sh b/echo-js/docker/run-machine-console.sh new file mode 100755 index 00000000..2c595c16 --- /dev/null +++ b/echo-js/docker/run-machine-console.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +cartesi-machine \ + --ram-length=128Mi \ + --rollup \ + --flash-drive=label:dapp,filename:dapp.ext2 \ + --flash-drive=label:root,filename:rootfs.ext2 \ + --ram-image=linux-5.5.19-ctsi-5.bin \ + --rom-image=rom.bin \ + -i \ + -- "/bin/sh" diff --git a/echo-js/docker/shasumfile b/echo-js/docker/shasumfile new file mode 100644 index 00000000..527836b1 --- /dev/null +++ b/echo-js/docker/shasumfile @@ -0,0 +1,3 @@ +88ec5b0a8c4f29c1f64189c07d222628b838078d *rom.bin +f2febaa5f9296d42756e6fe74e062fdb334f7d84 *rootfs.ext2 +c8c986e0890b624fe52a556a5a817c502f0bb2f0 *linux-5.5.19-ctsi-5.bin diff --git a/echo-js/entrypoint.sh b/echo-js/entrypoint.sh new file mode 100755 index 00000000..9f949ccc --- /dev/null +++ b/echo-js/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Copyright 2022 Cartesi Pte. Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# +set -e +rollup-init qjs server/src/echo-server.js diff --git a/echo-js/server/src/echo-server.js b/echo-js/server/src/echo-server.js new file mode 100644 index 00000000..74edd8f6 --- /dev/null +++ b/echo-js/server/src/echo-server.js @@ -0,0 +1,81 @@ +import fetch from './modules/fetch.js'; +import {getenv} from 'std'; + +const ROLLUP_ADDRESS = getenv('ROLLUP_HTTP_SERVER_URL'); + +async function handle_advance(data) { + print(`Received advance request data ${JSON.stringify(data)}`); + print('Adding notice'); + const response = await fetch(`${ROLLUP_ADDRESS}/notice`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body: { + payload: data.payload, + }, + }); + print(`Received notice status ${response.status} body ${JSON.stringify(response.json())}`); + return 'accept'; +} + +async function handle_inspect(data) { + print('Received inspect request data ', data); + print('Adding report'); + const response = await fetch(`${ROLLUP_ADDRESS}/report`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body: { + payload: data.payload, + }, + }); + print(`Received report status ${response.status}`); + return 'accept'; +} + +async function main() { + print(`HTTP rollup_server url is ${ROLLUP_ADDRESS}`) + let body = { + status: 'accept' + }; + while (true) { + print('Sending finish'); + const response = await fetch(`${ROLLUP_ADDRESS}/finish`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body, + }); + print(`Received finish status ${response.status}`); + if (response.status === 202) { + print('No pending rollup request, trying again'); + } else { + let rollup_request = response.json(); + let metadata = rollup_request.data.metadata; + + if (metadata.epoch_index === 0 && metadata.input_index === 0) { + let rollup_address = metadata.msg_sender; + print(`Captured rollup address: ${rollup_address}`) + } else { + switch (rollup_request.request_type) { + case 'advance_state': + body.status = await handle_advance(rollup_request.data); + break; + case 'inspect_state': + body.status = await handle_inspect(rollup_request.data); + break; + } + } + } + } +} + +main(); + + diff --git a/echo-js/server/src/modules/fetch.js b/echo-js/server/src/modules/fetch.js new file mode 100644 index 00000000..dd8dc24e --- /dev/null +++ b/echo-js/server/src/modules/fetch.js @@ -0,0 +1,150 @@ +/** + * FetchToCurl Strongly inspired by https://github.com/leoek/fetch-to-curl + */ + +import * as std from "std"; +import * as os from "os"; + +function generateMethod(options) { + const method = options.method; + if (!method) return ''; + const type = { + GET: ' -X "GET"', + POST: ' -X "POST"', + PUT: ' -X "PUT"', + PATCH: ' -X "PATCH"', + DELETE: ' -X "DELETE"', + HEAD: ' -X "HEAD"', + OPTIONS: ' -X "OPTIONS"' + }; + return type[method.toUpperCase()] || ''; +} + +function isInstanceOfHeaders(val) { + if (typeof Headers !== "function") { + /** + * Environment does not support the Headers constructor + * old internet explorer? + */ + return false; + } + return val instanceof Headers; +} + +function getHeaderString(name, val) { + return ` -H "${name}: ${`${val}`.replace(/(\\|")/g, '\\$1')}"`; +} + +function generateHeader(options = {}) { + const {headers} = options; + let isEncode = false; + let headerParam = ''; + if (isInstanceOfHeaders(headers)) { + headers.forEach((val, name) => { + if (name.toLocaleLowerCase() !== 'content-length') { + headerParam += getHeaderString(name, val); + } + if (name.toLocaleLowerCase() === 'accept-encoding') { + isEncode = true; + } + }) + } else if (headers) { + Object.keys(headers).map(name => { + if (name.toLocaleLowerCase() !== 'content-length') { + headerParam += getHeaderString(name, headers[name]); + } + if (name.toLocaleLowerCase() === 'accept-encoding') { + isEncode = true; + } + }); + } + return { + params: headerParam, + isEncode, + }; +} + +function generateBody(body) { + if (!body) return ''; + if (typeof body === "object") { + return ` -d '${JSON.stringify(body)}'`; + } + return ` -d '${body}'`; +} + +function generateCompress(isEncode) { + return isEncode ? ' --compressed' : ''; +} + +function fetchToCurl(requestInfo, requestInit) { + let url, options; + /** + * initialization with an empty object is done here to + * keep everything backwards compatible to 0.4.0 and below + */ + if (typeof requestInfo === "string" || requestInfo instanceof URL) { + url = requestInfo; + options = requestInit || {}; + } else { + url = (requestInfo || {}).url + options = requestInfo || {} + } + const {body} = options; + const headers = generateHeader(options); + return `curl -s --connect-timeout 99999 -w '%{json}' '${url}'${generateMethod(options)}${headers.params || ''}${generateBody(body)}${generateCompress(headers.isEncode)}`; +} + +export default (resource, init) => { + // curl command + let curlCmd = fetchToCurl(resource, init); + // exec curl command in subprocess + let spErr = {}; + let curlOutputFile = std.popen(curlCmd, 'r', spErr); + let curlOutput = curlOutputFile.readAsString(); + curlOutputFile.close(); + + if (curlOutput.indexOf('}{') > -1) { + curlOutput = curlOutput.replace('}{', '},{'); + } + + if (curlOutput.indexOf('[]') === 0) { + curlOutput = '{},' + curlOutput.substring(2); + } + + if (curlOutput.indexOf(']{') > -1) { + curlOutput = curlOutput.replace(']{', '],{'); + } + + if (curlOutput.charAt(0) !== '{' && curlOutput.charAt(0) !== '[') { + curlOutput = '{},' + curlOutput.substring(curlOutput.indexOf("{")); + } + + let data, meta; + + [ + data, + meta, + ] = JSON.parse(`[${curlOutput}]`); + + const responseUrl = resource; + let responseStatus = meta.http_code; + let responseOk = responseStatus >= 200 && responseStatus < 300; + + return new Promise((resolve, reject) => { + const response = { // TODO fill properties (https://developer.mozilla.org/en-US/docs/Web/API/Response) + headers: {}, // TODO + ok: responseOk, + url: responseUrl, + status: responseStatus, + type: 'json', + text: () => JSON.stringify(data), + json: () => data, + }; + + if (responseOk) { + resolve(response); + } else { + reject(response); + } + }); +};