diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index e337aa6..e2f7441 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -85,8 +85,7 @@ jobs: path: | deployments/localhost export - key: restore-artifacts-${{ hashFiles('docker-compose-deploy.yml', 'docker-compose.override.yml') }} - + key: restore-artifacts-${{ hashFiles('docker-compose.yml', docker-compose.override.yml') }} # Install dependencies - name: Install Yarn diff --git a/Dockerfile b/Dockerfile index e2fb2af..63685e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker.io/docker/dockerfile:1.4 -FROM cartesi/toolchain:0.13.0 as go-build +FROM cartesi/toolchain:0.14.0 as go-build # Install Go build dependencies RUN < 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": 3458, - "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/deployments/localhost/Bitmask.json b/deployments/localhost/Bitmask.json index fae7217..e1cac6c 100644 --- a/deployments/localhost/Bitmask.json +++ b/deployments/localhost/Bitmask.json @@ -1,19 +1,19 @@ { "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F", "abi": [], - "transactionHash": "0x40c6220225cca89ad21acb3fd797b12156d2f5fe2a48efde434c37f675aec792", + "transactionHash": "0xe803442e02f581cb2fd81874d08be0ca877b05855e5f6662d57879a87b7f71ae", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F", "transactionIndex": 0, - "gasUsed": "164746", + "gasUsed": "164782", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x17f91c11f9e45b6355ffb550bdca77e8822f107c121c492ad4eba310a41ee98a", - "transactionHash": "0x40c6220225cca89ad21acb3fd797b12156d2f5fe2a48efde434c37f675aec792", + "blockHash": "0x18734c35db113e06cba64a7b153b161aa882a7fa3591628cd6efc0d9ea19b167", + "transactionHash": "0xe803442e02f581cb2fd81874d08be0ca877b05855e5f6662d57879a87b7f71ae", "logs": [], "blockNumber": 7, - "cumulativeGasUsed": "164746", + "cumulativeGasUsed": "164782", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/BitsManipulation.json b/deployments/localhost/BitsManipulation.json index a19a679..42bfba1 100644 --- a/deployments/localhost/BitsManipulation.json +++ b/deployments/localhost/BitsManipulation.json @@ -88,19 +88,19 @@ "type": "function" } ], - "transactionHash": "0x6465ca2cb0dcec650de6881abfc1c0c8efc793fca0f40db1a06ddbea92a12d84", + "transactionHash": "0x41574fb54d6f99fa19472887ac9a09629f3cfc1c40edd4bde84f5d02235190f8", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", "transactionIndex": 0, - "gasUsed": "377537", + "gasUsed": "377635", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb8429b19eb501dbbdf2869eb2f30541020fa1d2ef5ea1afc1ef8244b4c70dc18", - "transactionHash": "0x6465ca2cb0dcec650de6881abfc1c0c8efc793fca0f40db1a06ddbea92a12d84", + "blockHash": "0xb9139d64ea17c0443f37d395d0b807538b1077cac98456dac34862eb37973564", + "transactionHash": "0x41574fb54d6f99fa19472887ac9a09629f3cfc1c40edd4bde84f5d02235190f8", "logs": [], "blockNumber": 6, - "cumulativeGasUsed": "377537", + "cumulativeGasUsed": "377635", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/BitsManipulationLibrary.json b/deployments/localhost/BitsManipulationLibrary.json index 5afef8a..e5fbc01 100644 --- a/deployments/localhost/BitsManipulationLibrary.json +++ b/deployments/localhost/BitsManipulationLibrary.json @@ -88,19 +88,19 @@ "type": "function" } ], - "transactionHash": "0x1c79de8214ea1b5dff1bb3c4dd4ae1d8c350b6d40702324ce883b7cadde87a32", + "transactionHash": "0x4480883581e4ca737ada80ce43e40f7cb679737b437352d22b47fe9eb5419aff", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "transactionIndex": 0, - "gasUsed": "198644", + "gasUsed": "198690", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfdad8ad98561393362110ed3fc9cec18964230a36096ddcbfaa2b25858f46bb9", - "transactionHash": "0x1c79de8214ea1b5dff1bb3c4dd4ae1d8c350b6d40702324ce883b7cadde87a32", + "blockHash": "0x9a18da4fa64af7808e9fe4246c26b0b760b85dbfe8ee7620b569b97094ea2a31", + "transactionHash": "0x4480883581e4ca737ada80ce43e40f7cb679737b437352d22b47fe9eb5419aff", "logs": [], "blockNumber": 1, - "cumulativeGasUsed": "198644", + "cumulativeGasUsed": "198690", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/CartesiDAppFactory.json b/deployments/localhost/CartesiDAppFactory.json index 4d6d0b5..2d4e5c1 100644 --- a/deployments/localhost/CartesiDAppFactory.json +++ b/deployments/localhost/CartesiDAppFactory.json @@ -1,112 +1,32 @@ { - "address": "0x7Cc41aC3135f03F1944136c99Ea6cBD18F112804", + "address": "0x428c077Ba15358B81C268A388606a722Cd51aB6B", "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", + "internalType": "contract IConsensus", + "name": "consensus", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "dappOwner", "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" + "internalType": "bytes32", + "name": "templateHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "contract CartesiDApp", + "name": "application", + "type": "address" } ], "name": "ApplicationCreated", @@ -115,33 +35,30 @@ { "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "diamondCut", - "outputs": [ + "internalType": "contract IConsensus", + "name": "_consensus", + "type": "address" + }, { "internalType": "address", - "name": "facetAddress", + "name": "_dappOwner", "type": "address" }, { - "internalType": "enum IDiamondCut.FacetCutAction", - "name": "action", - "type": "uint8" + "internalType": "bytes32", + "name": "_templateHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_salt", + "type": "bytes32" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "diamondCutFacet", + "name": "calculateApplicationAddress", "outputs": [ { - "internalType": "contract IDiamondCut", + "internalType": "address", "name": "", "type": "address" } @@ -150,79 +67,55 @@ "type": "function" }, { - "inputs": [], - "name": "diamondInit", - "outputs": [ + "inputs": [ { - "internalType": "contract DiamondInit", - "name": "", + "internalType": "contract IConsensus", + "name": "_consensus", "type": "address" + }, + { + "internalType": "address", + "name": "_dappOwner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_templateHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_salt", + "type": "bytes32" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "feeManagerBank", + "name": "newApplication", "outputs": [ { - "internalType": "contract IBank", + "internalType": "contract CartesiDApp", "name": "", "type": "address" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "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" + "internalType": "contract IConsensus", + "name": "_consensus", + "type": "address" + }, + { + "internalType": "address", + "name": "_dappOwner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_templateHash", + "type": "bytes32" } ], "name": "newApplication", @@ -237,242 +130,108 @@ "type": "function" } ], - "transactionHash": "0xae44d345d30e86e6826be19723228d3f7a4cf46946f401646a07c3b4f184e3ea", + "transactionHash": "0x6ebdec2adfa6ba8d8f87495675eedb82cc1c757b5ba40cd9e5cd837e0aebd860", "receipt": { "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": null, "transactionIndex": 0, - "gasUsed": "3308820", + "gasUsed": "1616177", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x32e2a2cb2ee9dc2c127e7f745b1b66a9cb242e76090047ec9d99fb3029436e0e", - "transactionHash": "0xae44d345d30e86e6826be19723228d3f7a4cf46946f401646a07c3b4f184e3ea", + "blockHash": "0x7a4008281a36af21ed9b517642ff36273189732108ab8f9426843809f0bce090", + "transactionHash": "0x6ebdec2adfa6ba8d8f87495675eedb82cc1c757b5ba40cd9e5cd837e0aebd860", "logs": [], - "blockNumber": 29, - "cumulativeGasUsed": "3308820", + "blockNumber": 18, + "cumulativeGasUsed": "1616177", "status": 1, "byzantium": true }, - "args": [ - { - "diamondCutFacet": "0x10dc33852b996A4C8A391d6Ed224FD89A3aD1ceE", - "diamondInit": "0xCbEDAB3193dc8027cc403a01cE054695a08E2F34", - "feeManagerBank": "0x15d929CD2c7e5b1F74Ac1D014322137027eD9Fbb", - "diamondCut": [ - { - "facetAddress": "0x8339b06c37d488d51aB838f6C758D61ddb1F1C6c", - "functionSelectors": [ - "0xcdffacc6", - "0x52ef6b2c", - "0xadfca15e", - "0x7a0ed627", - "0x01ffc9a7" - ], - "action": 0 - }, - { - "facetAddress": "0x19C65463Eb32Ff190062686b4ce150Ea1BD80988", - "functionSelectors": [ - "0x8da5cb5b", - "0xf2fde38b" - ], - "action": 0 - }, - { - "facetAddress": "0x0328426f3cf581F1Cf5Ba3492a3d1C5AB551de62", - "functionSelectors": [ - "0xcb1061a6" - ], - "action": 0 - }, - { - "facetAddress": "0xCF8E4cb394805b96290FEcE429E98613aB80b1c3", - "functionSelectors": [ - "0x15e55ce5", - "0x150b7a02" - ], - "action": 0 - }, - { - "facetAddress": "0x1ab5f2688Faec8Dd89e0E2BF23506dB4A4EE5eCA", - "functionSelectors": [ - "0x2abfe7b3", - "0x74956b94" - ], - "action": 0 - }, - { - "facetAddress": "0x81823BDB8ae08E546AD1eCcDa910Ab32B7253343", - "functionSelectors": [ - "0x6e964cea", - "0xa859b983", - "0xe8f56171", - "0xde7a8d11", - "0x7a5bf67c" - ], - "action": 0 - }, - { - "facetAddress": "0xeA8538B194742b992B19e694C13D63120908880e", - "functionSelectors": [ - "0xf32078e8", - "0x1ab6dcab", - "0xa459600e", - "0xe7955244" - ], - "action": 0 - }, - { - "facetAddress": "0xfE9874EecC53aC5076f5f9c81C880F36D7b52488", - "functionSelectors": [ - "0x6190d81e", - "0x3c0d9958", - "0xa2382036", - "0xf3af7efd", - "0x10517cfc", - "0x8021be81", - "0x83552b4d", - "0xa981588a", - "0x3ad58a27", - "0x5e439a0c", - "0x4f8192c9" - ], - "action": 0 - }, - { - "facetAddress": "0x98Bd941FFa18D10328eF1dea76a146AB6FD78Ee4", - "functionSelectors": [ - "0xbd66528a", - "0x82ae9ef7", - "0x7864b77d", - "0xb97dd9e2", - "0xa3a40ea5", - "0xddf7bcf0", - "0xe17ba012", - "0x54ee1da5", - "0x61b12c66" - ], - "action": 0 - }, - { - "facetAddress": "0x2596c9892cD4c997e6cE22745a2eF8256b0B171f", - "functionSelectors": [ - "0x101494ce", - "0xf6023815", - "0x8219fda4", - "0xd2992f54", - "0x55564a70", - "0xcc8a2451", - "0x1fcc449e" - ], - "action": 0 - } - ] - } - ], + "args": [], "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n AppConfig calldata _appConfig\\n ) public returns (CartesiDApp) {\\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\":\"0xd680ad826ce3ad58352d7cc25cff0ea8b77d0ed86cd8cf45bda75ddafdb3fcb0\",\"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(\\n AppConfig calldata _appConfig\\n ) external 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\":\"0x94983667134381b92e74f48bcf7eba2c53f87f4c36e840f9bec7172e64e2720d\",\"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(\\n address _facet\\n ) external view 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(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xdc5991b0218ab6b2cd78983c19f74a789a79ec9a9ba756ae05c8dcd512c13e38\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\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\":\"0x581eb846bee3d62731f4fc5bf21aa9cf744f491075941de685797f107e5d06f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"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(\\n address payable[] memory _validators\\n ) private {\\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\":\"0xab936fa5e183f87bb4421ea393b10d37eaf0ab648ad6f0d8d6be49d545a0b644\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x60e06040523480156200001157600080fd5b5060405162003159380380620031598339810160408190526200003491620002d9565b80516001600160a01b039081166080526020820151811660a05260408201511660c05260005b8160600151518110156200012f57600082606001518281518110620000835762000083620004e0565b60209081029190910181015182546001810184556000938452928290208151600294850290910180546001600160a01b039092166001600160a01b0319831681178255938301519294909384926001600160a81b0319161790600160a01b908490811115620000f657620000f6620004f6565b0217905550604082015180516200011891600184019160209091019062000137565b5050508062000127906200050c565b90506200005a565b505062000534565b82805482825590600052602060002090600701600890048101928215620001d85791602002820160005b83821115620001a457835183826101000a81548163ffffffff021916908360e01c0217905550926020019260040160208160030104928301926001030262000161565b8015620001d65782816101000a81549063ffffffff0219169055600401602081600301049283019260010302620001a4565b505b50620001e6929150620001ea565b5090565b5b80821115620001e65760008155600101620001eb565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200023c576200023c62000201565b60405290565b604051606081016001600160401b03811182821017156200023c576200023c62000201565b604051601f8201601f191681016001600160401b038111828210171562000292576200029262000201565b604052919050565b6001600160a01b0381168114620002b057600080fd5b50565b60006001600160401b03821115620002cf57620002cf62000201565b5060051b60200190565b60006020808385031215620002ed57600080fd5b82516001600160401b03808211156200030557600080fd5b90840190608082870312156200031a57600080fd5b6200032462000217565b825162000331816200029a565b81528284015162000342816200029a565b81850152604083015162000356816200029a565b60408201526060830151828111156200036e57600080fd5b80840193505086601f8401126200038457600080fd5b82516200039b6200039582620002b3565b62000267565b81815260059190911b84018501908581019089831115620003bb57600080fd5b8686015b83811015620004cd57805186811115620003d857600080fd5b87016060818d03601f19011215620003ef57600080fd5b620003f962000242565b8982015162000408816200029a565b81526040820151600381106200041d57600080fd5b818b01526060820151888111156200043457600080fd5b8083019250508c603f8301126200044a57600080fd5b898201516200045d6200039582620002b3565b81815260059190911b8301604001908b8101908f8311156200047e57600080fd5b6040850194505b82851015620004b75784516001600160e01b031981168114620004a757600080fd5b8252938c0193908c019062000485565b60408401525050845250918701918701620003bf565b5060608401525090979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6000600182016200052d57634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c051612be2620005776000396000818160f1015261022201526000818161011901526102ce01526000818160c9015261017c0152612be26000f3fe60806040523480156200001157600080fd5b50600436106200005e5760003560e01c806304c01cc7146200006357806394a28f321462000093578063a051e9b314620000c3578063aa9a6e9114620000eb578063e6ee1d4f1462000113575b600080fd5b6200007a6200007436600462000456565b6200013b565b6040516200008a92919062000493565b60405180910390f35b620000aa620000a4366004620004b9565b62000176565b6040516001600160a01b0390911681526020016200008a565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b600081815481106200014c57600080fd5b60009182526020909120600290910201546001600160a01b0381169150600160a01b900460ff1682565b600080307f0000000000000000000000000000000000000000000000000000000000000000604051620001a99062000448565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620001dd573d6000803e3d6000fd5b5090506000604051806101000160405280856020013581526020018560400135815260200185606001358152602001856080013581526020018560a0013581526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018560c001602081019062000264919062000523565b6001600160a01b031681526020016200028160e087018762000543565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509390945250506040519293506001600160a01b03851692631f931c1c92507f00000000000000000000000000000000000000000000000000000000000000009063af52770160e01b9062000307908790602401620005dd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e086901b909216825262000350939291600401620006b8565b600060405180830381600087803b1580156200036b57600080fd5b505af115801562000380573d6000803e3d6000fd5b5050506001600160a01b038316905063f2fde38b620003a3602087018762000523565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620003e557600080fd5b505af1158015620003fa573d6000803e3d6000fd5b50505050816001600160a01b03167f43883daeb0f23afe0fbb9658d1d4c08379520e9654a30f7ea3a9fb3a8f5195bb8560405162000439919062000a2b565b60405180910390a25092915050565b6120df8062000ace83390190565b6000602082840312156200046957600080fd5b5035919050565b600381106200048f57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b038316815260408101620004b2602083018462000470565b9392505050565b600060208284031215620004cc57600080fd5b813567ffffffffffffffff811115620004e457600080fd5b82016101008185031215620004b257600080fd5b6001600160a01b03811681146200050e57600080fd5b50565b80356200051e81620004f8565b919050565b6000602082840312156200053657600080fd5b8135620004b281620004f8565b6000808335601e198436030181126200055b57600080fd5b83018035915067ffffffffffffffff8211156200057757600080fd5b6020019150600581901b36038213156200059057600080fd5b9250929050565b600081518084526020808501945080840160005b83811015620005d25781516001600160a01b031687529582019590820190600101620005ab565b509495945050505050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a083015160018060a01b0380821660c08501528060c08601511660e0850152505060e08301516101008081850152506200065261012084018262000597565b949350505050565b6001600160e01b0319169052565b6000815180845260005b81811015620006905760208185018101518683018201520162000672565b81811115620006a3576000602083870101525b50601f01601f19169290920160200192915050565b60608152600060608201855480825260808401915060808160051b8501018760005260208060002060005b848110156200096d57878403607f1901865281546001600160a01b038116855260608501906200071d85870160a083901c60ff1662000470565b506060604086015260018381018054808452600091825260208083209401905b80600784011015620008055784546200075a838260e01b6200065a565b6001600160e01b031962000777848b0160c084901b83166200065a565b6200078b60408501828460a01b166200065a565b6200079f60608501828460801b166200065a565b620007b360808501828460601b166200065a565b620007c760a08501828460401b166200065a565b620007da60c0850182848d1b166200065a565b620007eb60e085018284166200065a565b50506101008201915083850194506008830192506200073d565b93549380831015620008295762000820828660e01b6200065a565b91830191908701905b8083101562000855576200084c8260c087901b6001600160e01b0319166200065a565b91830191908701905b808310156200088157620008788260a087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008ad57620008a482608087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008d957620008d082606087901b6001600160e01b0319166200065a565b91830191908701905b808310156200090557620008fc82604087901b6001600160e01b0319166200065a565b91830191908701905b808310156200092f576200092682868a1b6001600160e01b0319166200065a565b91830191908701905b8083101562000953576200094e826001600160e01b031987166200065a565b908701905b5098860198965050506002929092019150600101620006e3565b50506001600160a01b03881690860152848103604086015262000991818762000668565b98975050505050505050565b6000808335601e19843603018112620009b557600080fd5b830160208101925035905067ffffffffffffffff811115620009d657600080fd5b8060051b36038313156200059057600080fd5b8183526000602080850194508260005b85811015620005d257813562000a0f81620004f8565b6001600160a01b031687529582019590820190600101620009f9565b602081526000823562000a3e81620004f8565b60018060a01b038116602084015250602083013560408301526040830135606083015260608301356080830152608083013560a083015260a083013560c083015262000a8d60c0840162000511565b6001600160a01b03811660e08401525062000aac60e08401846200099d565b6101008481015262000ac461012085018284620009e9565b9594505050505056fe6080604052604051620020df380380620020df833981016040819052620000269162000ddc565b6200003c826200015660201b620000b01760201c565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620000535750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000c657620000c662000e14565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038516815290810160008152602001828152508260008151811062000119576200011962000e14565b60200260200101819052506200014c82600060405180602001604052806000815250620001da60201b620001331760201c565b5050505062001067565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040516000805160206200204b833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546000805160206200204b8339815191529061ffff811690819060009060071615620002395750600381901c60009081526001840160205260409020545b60005b8751811015620002d557620002bb83838a848151811062000261576200026162000e14565b6020026020010151600001518b858151811062000282576200028262000e14565b6020026020010151602001518c8681518110620002a357620002a362000e14565b6020026020010151604001516200036760201b60201c565b909350915080620002cc8162000e56565b9150506200023c565b50828214620002f25760028401805461ffff191661ffff84161790555b60078216156200031557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200034a9392919062000ecf565b60405180910390a16200035e868662000b76565b50505050505050565b600080806000805160206200204b83398151915290506000845111620003e85760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084015b60405180910390fd5b6000856002811115620003ff57620003ff62000e2a565b0362000585576200042a866040518060600160405280602481526020016200206b6024913962000d9b565b60005b84518110156200057e5760008582815181106200044e576200044e62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c15620004f15760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620003df565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a819003620005565760038c901c600090815260018601602052604081209b909b555b8b620005628162000e56565b9c50505050508080620005759062000e56565b9150506200042d565b5062000b6a565b60018560028111156200059c576200059c62000e2a565b03620007b557620005c786604051806060016040528060288152602001620020b76028913962000d9b565b60005b84518110156200057e576000858281518110620005eb57620005eb62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c308103620006825760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401620003df565b896001600160a01b0316816001600160a01b031603620006fa5760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401620003df565b6001600160a01b038116620007675760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401620003df565b506001600160e01b031990911660009081526020849052604090206001600160601b03919091166001600160601b031960608a901b1617905580620007ac8162000e56565b915050620005ca565b6002856002811115620007cc57620007cc62000e2a565b0362000b11576001600160a01b03861615620008515760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620003df565b600388901c6007891660005b865181101562000aec5760008a90036200089e57826200087d8162000fd6565b60008181526001870160205260409020549b50935060079250620008ae9050565b81620008aa8162000fd6565b9250505b6000806000808a8581518110620008c957620008c962000e14565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6200096b5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620003df565b30606082901c03620009d75760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620003df565b600587901b8f901b94506001600160e01b03198086169083161462000a29576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166001600160601b0383161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e016905085821462000a90576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c17905562000ab4565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b8460000362000ad357600086815260018801602052604081208190559c505b505050808062000ae39062000e56565b9150506200085d565b508062000afb83600862000ff0565b62000b07919062001012565b9950505062000b6a565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401620003df565b50959694955050505050565b6001600160a01b03821662000c005780511562000bfc5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401620003df565b5050565b600081511162000c795760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401620003df565b6001600160a01b038216301462000caf5762000caf826040518060600160405280602881526020016200208f6028913962000d9b565b600080836001600160a01b03168360405162000ccc91906200102d565b600060405180830381855af49150503d806000811462000d09576040519150601f19603f3d011682016040523d82523d6000602084013e62000d0e565b606091505b50915091508162000d955780511562000d3d578060405162461bcd60e51b8152600401620003df91906200104b565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401620003df565b50505050565b813b818162000d955760405162461bcd60e51b8152600401620003df91906200104b565b80516001600160a01b038116811462000dd757600080fd5b919050565b6000806040838503121562000df057600080fd5b62000dfb8362000dbf565b915062000e0b6020840162000dbf565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000e6b5762000e6b62000e40565b5060010190565b60005b8381101562000e8f57818101518382015260200162000e75565b8381111562000d955750506000910152565b6000815180845262000ebb81602086016020860162000e72565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000fa457898403607f19018652815180516001600160a01b0316855283810151898601906003811062000f4057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f8e5783516001600160e01b031916825292860192600192909201919086019062000f62565b5097850197955050509082019060010162000ef8565b50506001600160a01b038a1690880152868103604088015262000fc8818962000ea1565b9a9950505050505050505050565b60008162000fe85762000fe862000e40565b506000190190565b60008160001904831182151516156200100d576200100d62000e40565b500290565b6000821982111562001028576200102862000e40565b500190565b600082516200104181846020870162000e72565b9190910192915050565b60208152600062001060602083018462000ea1565b9392505050565b610fb480620010776000396000f3fe60806040523661000b57005b600080356001600160e01b0319168152600080516020610eeb8339815191526020819052604090912054819060601c8061008c5760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460448201526064015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100ab573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020610eeb833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54600080516020610eeb8339815191529061ffff8116908190600090600716156101905750600381901c60009081526001840160205260409020545b60005b87518110156102175761020083838a84815181106101b3576101b3610cb3565b6020026020010151600001518b85815181106101d1576101d1610cb3565b6020026020010151602001518c86815181106101ef576101ef610cb3565b6020026020010151604001516102a3565b90935091508061020f81610cdf565b915050610193565b508282146102335760028401805461ffff191661ffff84161790555b600782161561025557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161028893929190610d66565b60405180910390a161029a8686610a7f565b50505050505050565b60008080600080516020610eeb8339815191529050600084511161031d5760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401610083565b600085600281111561033157610331610cf8565b0361049e5761035886604051806060016040528060248152602001610f0b60249139610c92565b60005b845181101561049857600085828151811061037857610378610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104115760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b6064820152608401610083565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104755760038c901c600090815260018601602052604081209b909b555b8b61047f81610cdf565b9c5050505050808061049090610cdf565b91505061035b565b50610a73565b60018560028111156104b2576104b2610cf8565b036106e1576104d986604051806060016040528060288152602001610f5760289139610c92565b60005b84518110156104985760008582815181106104f9576104f9610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c30810361058e5760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401610083565b896001600160a01b0316816001600160a01b0316036106155760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610083565b6001600160a01b0381166106915760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610083565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b16179055806106d981610cdf565b9150506104dc565b60028560028111156106f5576106f5610cf8565b03610a1b576001600160a01b038616156107705760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b6064820152608401610083565b600388901c6007891660005b86518110156109fb5760008a90036107b8578261079881610e66565b60008181526001870160205260409020549b509350600792506107c69050565b816107c281610e66565b9250505b6000806000808a85815181106107de576107de610cb3565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c61087e5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610083565b30606082901c036108e85760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610083565b600587901b8f901b94506001600160e01b03198086169083161461093e576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146109a3576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c1790556109c7565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b846000036109e557600086815260018801602052604081208190559c505b50505080806109f390610cdf565b91505061077c565b5080610a08836008610e7d565b610a129190610e9c565b99505050610a73565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401610083565b50959694955050505050565b6001600160a01b038216610b0657805115610b025760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401610083565b5050565b6000815111610b7d5760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401610083565b6001600160a01b0382163014610baf57610baf82604051806060016040528060288152602001610f2f60289139610c92565b600080836001600160a01b031683604051610bca9190610eb4565b600060405180830381855af49150503d8060008114610c05576040519150601f19603f3d011682016040523d82523d6000602084013e610c0a565b606091505b509150915081610c8c57805115610c35578060405162461bcd60e51b81526004016100839190610ed0565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401610083565b50505050565b813b8181610c8c5760405162461bcd60e51b81526004016100839190610ed0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610cf157610cf1610cc9565b5060010190565b634e487b7160e01b600052602160045260246000fd5b60005b83811015610d29578181015183820152602001610d11565b83811115610c8c5750506000910152565b60008151808452610d52816020860160208601610d0e565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610e3657898403607f19018652815180516001600160a01b03168552838101518986019060038110610dd557634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610e215783516001600160e01b0319168252928601926001929092019190860190610df7565b50978501979550505090820190600101610d8f565b50506001600160a01b038a16908801528681036040880152610e588189610d3a565b9a9950505050505050505050565b600081610e7557610e75610cc9565b506000190190565b6000816000190483118215151615610e9757610e97610cc9565b500290565b60008219821115610eaf57610eaf610cc9565b500190565b60008251610ec6818460208701610d0e565b9190910192915050565b602081526000610ee36020830184610d3a565b939250505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220b69d20db35c4d09a73e0fae3e21d3418a25fad2ce81b24fb3dc4d5be9801ee0264736f6c634300080d00334c69624469616d6f6e644375743a2043616e2774207265706c6163652066756ec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212208c9f838fc49aa6679eca5cd55b9149c489d8b7be3f357fb87d75c3dff286a30c64736f6c634300080d0033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200005e5760003560e01c806304c01cc7146200006357806394a28f321462000093578063a051e9b314620000c3578063aa9a6e9114620000eb578063e6ee1d4f1462000113575b600080fd5b6200007a6200007436600462000456565b6200013b565b6040516200008a92919062000493565b60405180910390f35b620000aa620000a4366004620004b9565b62000176565b6040516001600160a01b0390911681526020016200008a565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b620000aa7f000000000000000000000000000000000000000000000000000000000000000081565b600081815481106200014c57600080fd5b60009182526020909120600290910201546001600160a01b0381169150600160a01b900460ff1682565b600080307f0000000000000000000000000000000000000000000000000000000000000000604051620001a99062000448565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620001dd573d6000803e3d6000fd5b5090506000604051806101000160405280856020013581526020018560400135815260200185606001358152602001856080013581526020018560a0013581526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018560c001602081019062000264919062000523565b6001600160a01b031681526020016200028160e087018762000543565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509390945250506040519293506001600160a01b03851692631f931c1c92507f00000000000000000000000000000000000000000000000000000000000000009063af52770160e01b9062000307908790602401620005dd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e086901b909216825262000350939291600401620006b8565b600060405180830381600087803b1580156200036b57600080fd5b505af115801562000380573d6000803e3d6000fd5b5050506001600160a01b038316905063f2fde38b620003a3602087018762000523565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620003e557600080fd5b505af1158015620003fa573d6000803e3d6000fd5b50505050816001600160a01b03167f43883daeb0f23afe0fbb9658d1d4c08379520e9654a30f7ea3a9fb3a8f5195bb8560405162000439919062000a2b565b60405180910390a25092915050565b6120df8062000ace83390190565b6000602082840312156200046957600080fd5b5035919050565b600381106200048f57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b038316815260408101620004b2602083018462000470565b9392505050565b600060208284031215620004cc57600080fd5b813567ffffffffffffffff811115620004e457600080fd5b82016101008185031215620004b257600080fd5b6001600160a01b03811681146200050e57600080fd5b50565b80356200051e81620004f8565b919050565b6000602082840312156200053657600080fd5b8135620004b281620004f8565b6000808335601e198436030181126200055b57600080fd5b83018035915067ffffffffffffffff8211156200057757600080fd5b6020019150600581901b36038213156200059057600080fd5b9250929050565b600081518084526020808501945080840160005b83811015620005d25781516001600160a01b031687529582019590820190600101620005ab565b509495945050505050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a083015160018060a01b0380821660c08501528060c08601511660e0850152505060e08301516101008081850152506200065261012084018262000597565b949350505050565b6001600160e01b0319169052565b6000815180845260005b81811015620006905760208185018101518683018201520162000672565b81811115620006a3576000602083870101525b50601f01601f19169290920160200192915050565b60608152600060608201855480825260808401915060808160051b8501018760005260208060002060005b848110156200096d57878403607f1901865281546001600160a01b038116855260608501906200071d85870160a083901c60ff1662000470565b506060604086015260018381018054808452600091825260208083209401905b80600784011015620008055784546200075a838260e01b6200065a565b6001600160e01b031962000777848b0160c084901b83166200065a565b6200078b60408501828460a01b166200065a565b6200079f60608501828460801b166200065a565b620007b360808501828460601b166200065a565b620007c760a08501828460401b166200065a565b620007da60c0850182848d1b166200065a565b620007eb60e085018284166200065a565b50506101008201915083850194506008830192506200073d565b93549380831015620008295762000820828660e01b6200065a565b91830191908701905b8083101562000855576200084c8260c087901b6001600160e01b0319166200065a565b91830191908701905b808310156200088157620008788260a087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008ad57620008a482608087901b6001600160e01b0319166200065a565b91830191908701905b80831015620008d957620008d082606087901b6001600160e01b0319166200065a565b91830191908701905b808310156200090557620008fc82604087901b6001600160e01b0319166200065a565b91830191908701905b808310156200092f576200092682868a1b6001600160e01b0319166200065a565b91830191908701905b8083101562000953576200094e826001600160e01b031987166200065a565b908701905b5098860198965050506002929092019150600101620006e3565b50506001600160a01b03881690860152848103604086015262000991818762000668565b98975050505050505050565b6000808335601e19843603018112620009b557600080fd5b830160208101925035905067ffffffffffffffff811115620009d657600080fd5b8060051b36038313156200059057600080fd5b8183526000602080850194508260005b85811015620005d257813562000a0f81620004f8565b6001600160a01b031687529582019590820190600101620009f9565b602081526000823562000a3e81620004f8565b60018060a01b038116602084015250602083013560408301526040830135606083015260608301356080830152608083013560a083015260a083013560c083015262000a8d60c0840162000511565b6001600160a01b03811660e08401525062000aac60e08401846200099d565b6101008481015262000ac461012085018284620009e9565b9594505050505056fe6080604052604051620020df380380620020df833981016040819052620000269162000ddc565b6200003c826200015660201b620000b01760201c565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620000535750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000c657620000c662000e14565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038516815290810160008152602001828152508260008151811062000119576200011962000e14565b60200260200101819052506200014c82600060405180602001604052806000815250620001da60201b620001331760201c565b5050505062001067565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040516000805160206200204b833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546000805160206200204b8339815191529061ffff811690819060009060071615620002395750600381901c60009081526001840160205260409020545b60005b8751811015620002d557620002bb83838a848151811062000261576200026162000e14565b6020026020010151600001518b858151811062000282576200028262000e14565b6020026020010151602001518c8681518110620002a357620002a362000e14565b6020026020010151604001516200036760201b60201c565b909350915080620002cc8162000e56565b9150506200023c565b50828214620002f25760028401805461ffff191661ffff84161790555b60078216156200031557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200034a9392919062000ecf565b60405180910390a16200035e868662000b76565b50505050505050565b600080806000805160206200204b83398151915290506000845111620003e85760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084015b60405180910390fd5b6000856002811115620003ff57620003ff62000e2a565b0362000585576200042a866040518060600160405280602481526020016200206b6024913962000d9b565b60005b84518110156200057e5760008582815181106200044e576200044e62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c15620004f15760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620003df565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a819003620005565760038c901c600090815260018601602052604081209b909b555b8b620005628162000e56565b9c50505050508080620005759062000e56565b9150506200042d565b5062000b6a565b60018560028111156200059c576200059c62000e2a565b03620007b557620005c786604051806060016040528060288152602001620020b76028913962000d9b565b60005b84518110156200057e576000858281518110620005eb57620005eb62000e14565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c308103620006825760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401620003df565b896001600160a01b0316816001600160a01b031603620006fa5760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401620003df565b6001600160a01b038116620007675760405162461bcd60e51b815260206004820152603860248201526000805160206200202b83398151915260448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401620003df565b506001600160e01b031990911660009081526020849052604090206001600160601b03919091166001600160601b031960608a901b1617905580620007ac8162000e56565b915050620005ca565b6002856002811115620007cc57620007cc62000e2a565b0362000b11576001600160a01b03861615620008515760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620003df565b600388901c6007891660005b865181101562000aec5760008a90036200089e57826200087d8162000fd6565b60008181526001870160205260409020549b50935060079250620008ae9050565b81620008aa8162000fd6565b9250505b6000806000808a8581518110620008c957620008c962000e14565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6200096b5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620003df565b30606082901c03620009d75760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620003df565b600587901b8f901b94506001600160e01b03198086169083161462000a29576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166001600160601b0383161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e016905085821462000a90576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c17905562000ab4565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b8460000362000ad357600086815260018801602052604081208190559c505b505050808062000ae39062000e56565b9150506200085d565b508062000afb83600862000ff0565b62000b07919062001012565b9950505062000b6a565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401620003df565b50959694955050505050565b6001600160a01b03821662000c005780511562000bfc5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401620003df565b5050565b600081511162000c795760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401620003df565b6001600160a01b038216301462000caf5762000caf826040518060600160405280602881526020016200208f6028913962000d9b565b600080836001600160a01b03168360405162000ccc91906200102d565b600060405180830381855af49150503d806000811462000d09576040519150601f19603f3d011682016040523d82523d6000602084013e62000d0e565b606091505b50915091508162000d955780511562000d3d578060405162461bcd60e51b8152600401620003df91906200104b565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401620003df565b50505050565b813b818162000d955760405162461bcd60e51b8152600401620003df91906200104b565b80516001600160a01b038116811462000dd757600080fd5b919050565b6000806040838503121562000df057600080fd5b62000dfb8362000dbf565b915062000e0b6020840162000dbf565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000e6b5762000e6b62000e40565b5060010190565b60005b8381101562000e8f57818101518382015260200162000e75565b8381111562000d955750506000910152565b6000815180845262000ebb81602086016020860162000e72565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000fa457898403607f19018652815180516001600160a01b0316855283810151898601906003811062000f4057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f8e5783516001600160e01b031916825292860192600192909201919086019062000f62565b5097850197955050509082019060010162000ef8565b50506001600160a01b038a1690880152868103604088015262000fc8818962000ea1565b9a9950505050505050505050565b60008162000fe85762000fe862000e40565b506000190190565b60008160001904831182151516156200100d576200100d62000e40565b500290565b6000821982111562001028576200102862000e40565b500190565b600082516200104181846020870162000e72565b9190910192915050565b60208152600062001060602083018462000ea1565b9392505050565b610fb480620010776000396000f3fe60806040523661000b57005b600080356001600160e01b0319168152600080516020610eeb8339815191526020819052604090912054819060601c8061008c5760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460448201526064015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100ab573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020610eeb833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54600080516020610eeb8339815191529061ffff8116908190600090600716156101905750600381901c60009081526001840160205260409020545b60005b87518110156102175761020083838a84815181106101b3576101b3610cb3565b6020026020010151600001518b85815181106101d1576101d1610cb3565b6020026020010151602001518c86815181106101ef576101ef610cb3565b6020026020010151604001516102a3565b90935091508061020f81610cdf565b915050610193565b508282146102335760028401805461ffff191661ffff84161790555b600782161561025557600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161028893929190610d66565b60405180910390a161029a8686610a7f565b50505050505050565b60008080600080516020610eeb8339815191529050600084511161031d5760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401610083565b600085600281111561033157610331610cf8565b0361049e5761035886604051806060016040528060248152602001610f0b60249139610c92565b60005b845181101561049857600085828151811061037857610378610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104115760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b6064820152608401610083565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104755760038c901c600090815260018601602052604081209b909b555b8b61047f81610cdf565b9c5050505050808061049090610cdf565b91505061035b565b50610a73565b60018560028111156104b2576104b2610cf8565b036106e1576104d986604051806060016040528060288152602001610f5760289139610c92565b60005b84518110156104985760008582815181106104f9576104f9610cb3565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c30810361058e5760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b6064820152608401610083565b896001600160a01b0316816001600160a01b0316036106155760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610083565b6001600160a01b0381166106915760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610083565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b16179055806106d981610cdf565b9150506104dc565b60028560028111156106f5576106f5610cf8565b03610a1b576001600160a01b038616156107705760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b6064820152608401610083565b600388901c6007891660005b86518110156109fb5760008a90036107b8578261079881610e66565b60008181526001870160205260409020549b509350600792506107c69050565b816107c281610e66565b9250505b6000806000808a85815181106107de576107de610cb3565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c61087e5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610083565b30606082901c036108e85760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610083565b600587901b8f901b94506001600160e01b03198086169083161461093e576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146109a3576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c1790556109c7565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b846000036109e557600086815260018801602052604081208190559c505b50505080806109f390610cdf565b91505061077c565b5080610a08836008610e7d565b610a129190610e9c565b99505050610a73565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401610083565b50959694955050505050565b6001600160a01b038216610b0657805115610b025760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401610083565b5050565b6000815111610b7d5760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401610083565b6001600160a01b0382163014610baf57610baf82604051806060016040528060288152602001610f2f60289139610c92565b600080836001600160a01b031683604051610bca9190610eb4565b600060405180830381855af49150503d8060008114610c05576040519150601f19603f3d011682016040523d82523d6000602084013e610c0a565b606091505b509150915081610c8c57805115610c35578060405162461bcd60e51b81526004016100839190610ed0565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401610083565b50505050565b813b8181610c8c5760405162461bcd60e51b81526004016100839190610ed0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610cf157610cf1610cc9565b5060010190565b634e487b7160e01b600052602160045260246000fd5b60005b83811015610d29578181015183820152602001610d11565b83811115610c8c5750506000910152565b60008151808452610d52816020860160208601610d0e565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610e3657898403607f19018652815180516001600160a01b03168552838101518986019060038110610dd557634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610e215783516001600160e01b0319168252928601926001929092019190860190610df7565b50978501979550505090820190600101610d8f565b50506001600160a01b038a16908801528681036040880152610e588189610d3a565b9a9950505050505050505050565b600081610e7557610e75610cc9565b506000190190565b6000816000190483118215151615610e9757610e97610cc9565b500290565b60008219821115610eaf57610eaf610cc9565b500190565b60008251610ec6818460208701610d0e565b9190910192915050565b602081526000610ee36020830184610d3a565b939250505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220b69d20db35c4d09a73e0fae3e21d3418a25fad2ce81b24fb3dc4d5be9801ee0264736f6c634300080d00334c69624469616d6f6e644375743a2043616e2774207265706c6163652066756ec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212208c9f838fc49aa6679eca5cd55b9149c489d8b7be3f357fb87d75c3dff286a30c64736f6c634300080d0033", + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IConsensus\",\"name\":\"consensus\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"dappOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"templateHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"contract CartesiDApp\",\"name\":\"application\",\"type\":\"address\"}],\"name\":\"ApplicationCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract IConsensus\",\"name\":\"_consensus\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_templateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"}],\"name\":\"calculateApplicationAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IConsensus\",\"name\":\"_consensus\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_templateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_salt\",\"type\":\"bytes32\"}],\"name\":\"newApplication\",\"outputs\":[{\"internalType\":\"contract CartesiDApp\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IConsensus\",\"name\":\"_consensus\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dappOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_templateHash\",\"type\":\"bytes32\"}],\"name\":\"newApplication\",\"outputs\":[{\"internalType\":\"contract CartesiDApp\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"ApplicationCreated(address,address,bytes32,address)\":{\"details\":\"MUST be triggered on a successful call to `newApplication`.\",\"params\":{\"application\":\"The application\",\"consensus\":\"The initial consensus contract\",\"dappOwner\":\"The initial DApp owner\",\"templateHash\":\"The initial machine state hash\"}}},\"kind\":\"dev\",\"methods\":{\"calculateApplicationAddress(address,address,bytes32,bytes32)\":{\"details\":\"Beware that only the `newApplication` function with the `_salt` parameter is able to deterministically deploy an application.\",\"params\":{\"_consensus\":\"The initial consensus contract\",\"_dappOwner\":\"The initial DApp owner\",\"_salt\":\"The salt used to deterministically generate the DApp address\",\"_templateHash\":\"The initial machine state hash\"},\"returns\":{\"_0\":\"The deterministic application address\"}},\"newApplication(address,address,bytes32)\":{\"details\":\"On success, MUST emit an `ApplicationCreated` event.\",\"params\":{\"_consensus\":\"The initial consensus contract\",\"_dappOwner\":\"The initial DApp owner\",\"_templateHash\":\"The initial machine state hash\"},\"returns\":{\"_0\":\"The application\"}},\"newApplication(address,address,bytes32,bytes32)\":{\"details\":\"On success, MUST emit an `ApplicationCreated` event.\",\"params\":{\"_consensus\":\"The initial consensus contract\",\"_dappOwner\":\"The initial DApp owner\",\"_salt\":\"The salt used to deterministically generate the DApp address\",\"_templateHash\":\"The initial machine state hash\"},\"returns\":{\"_0\":\"The application\"}}},\"title\":\"Cartesi DApp Factory\",\"version\":1},\"userdoc\":{\"events\":{\"ApplicationCreated(address,address,bytes32,address)\":{\"notice\":\"A new application was deployed.\"}},\"kind\":\"user\",\"methods\":{\"calculateApplicationAddress(address,address,bytes32,bytes32)\":{\"notice\":\"Calculate the address of an application to be deployed deterministically.\"},\"newApplication(address,address,bytes32)\":{\"notice\":\"Deploy a new application.\"},\"newApplication(address,address,bytes32,bytes32)\":{\"notice\":\"Deploy a new application deterministically.\"}},\"notice\":\"Allows anyone to reliably deploy a new `CartesiDApp` contract.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/dapp/CartesiDAppFactory.sol\":\"CartesiDAppFactory\"},\"evmVersion\":\"paris\",\"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/CartesiMathV2.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 CartesiMathV2 {\\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 = n + 128;\\n _num = _num >> 128;\\n }\\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) {\\n n = n + 64;\\n _num = _num >> 64;\\n }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) {\\n n = n + 32;\\n _num = _num >> 32;\\n }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) {\\n n = n + 16;\\n _num = _num >> 16;\\n }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) {\\n n = n + 8;\\n _num = _num >> 8;\\n }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) {\\n n = n + 4;\\n _num = _num >> 4;\\n }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) {\\n n = n + 2;\\n _num = _num >> 2;\\n }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) {\\n n = n + 1;\\n }\\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 = n + 128;\\n _num = _num << 128;\\n }\\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 64;\\n _num = _num << 64;\\n }\\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 32;\\n _num = _num << 32;\\n }\\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 16;\\n _num = _num << 16;\\n }\\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 8;\\n _num = _num << 8;\\n }\\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 4;\\n _num = _num << 4;\\n }\\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 2;\\n _num = _num << 2;\\n }\\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 1;\\n }\\n\\n return n;\\n }\\n}\\n\",\"keccak256\":\"0x3208110a6cde8f74d144dc962c70346ab0d232b613a82ac371f1ab7bcf99cd56\",\"license\":\"Apache-2.0\"},\"@cartesi/util/contracts/MerkleV2.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 \\\"./CartesiMathV2.sol\\\";\\n\\nlibrary MerkleV2 {\\n using CartesiMathV2 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 && _logSizeOfReplacement >= 3 && _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(siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement, \\\"Proof length does not match\\\");\\n\\n for (uint256 i; i < siblings.length; i++) {\\n if ((_position & (size << i)) == 0) {\\n _replacement = keccak256(abi.encodePacked(_replacement, siblings[i]));\\n } else {\\n _replacement = keccak256(abi.encodePacked(siblings[i], _replacement));\\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) public pure returns (bytes32) {\\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) public pure returns (bytes32) {\\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(size << L_WORD_SIZE >= _data.length, \\\"data is bigger than drive\\\");\\n // the stack depth is log2(_data.length / 8) + 2\\n uint256 stack_depth = 2 + ((_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) public pure returns (bytes32) {\\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) public pure returns (bytes32) {\\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(abi.encodePacked(hashes[i], hashes[i + 1]));\\n }\\n\\n return calculateRootFromPowerOfTwo(newHashes);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x315a8d0fde92e153209207f0ec3aee323bfddc1c6857c5f1e245c781ae98c2b8\",\"license\":\"Apache-2.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ERC1155Receiver.sol\\\";\\n\\n/**\\n * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.\\n *\\n * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be\\n * stuck.\\n *\\n * @dev _Available since v3.1._\\n */\\ncontract ERC1155Holder is ERC1155Receiver {\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes memory\\n ) public virtual override returns (bytes4) {\\n return this.onERC1155Received.selector;\\n }\\n\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] memory,\\n uint256[] memory,\\n bytes memory\\n ) public virtual override returns (bytes4) {\\n return this.onERC1155BatchReceived.selector;\\n }\\n}\\n\",\"keccak256\":\"0x2e024ca51ce5abe16c0d34e6992a1104f356e2244eb4ccbec970435e8b3405e3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC1155Receiver.sol\\\";\\nimport \\\"../../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\\n }\\n}\\n\",\"keccak256\":\"0x3dd5e1a66a56f30302108a1da97d677a42b1daa60e503696b2bcbbf3e4c95bcb\",\"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/token/ERC721/utils/ERC721Holder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721Receiver.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC721Receiver} interface.\\n *\\n * Accepts all token transfers.\\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\\n */\\ncontract ERC721Holder is IERC721Receiver {\\n /**\\n * @dev See {IERC721Receiver-onERC721Received}.\\n *\\n * Always returns `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes memory\\n ) public virtual override returns (bytes4) {\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0x0108bf6a6ebd5f96678bed33a35947537263f96766131ee91461fb6485805028\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"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/common/CanonicalMachine.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Canonical Machine Constants Library\\n///\\n/// @notice Defines several constants related to the reference implementation\\n/// of the RISC-V machine that runs Linux, also known as the \\\"Cartesi Machine\\\".\\nlibrary CanonicalMachine {\\n /// @notice Base-2 logarithm of number of bytes.\\n type Log2Size is uint64;\\n\\n /// @notice Machine word size (8 bytes).\\n Log2Size constant WORD_LOG2_SIZE = Log2Size.wrap(3);\\n\\n /// @notice Machine address space size (2^64 bytes).\\n Log2Size constant MACHINE_LOG2_SIZE = Log2Size.wrap(64);\\n\\n /// @notice Keccak-256 output size (32 bytes).\\n Log2Size constant KECCAK_LOG2_SIZE = Log2Size.wrap(5);\\n\\n /// @notice Maximum input size (32 megabytes).\\n Log2Size constant INPUT_MAX_LOG2_SIZE = Log2Size.wrap(25);\\n\\n /// @notice Maximum voucher metadata memory range (2 megabytes).\\n Log2Size constant VOUCHER_METADATA_LOG2_SIZE = Log2Size.wrap(21);\\n\\n /// @notice Maximum notice metadata memory range (2 megabytes).\\n Log2Size constant NOTICE_METADATA_LOG2_SIZE = Log2Size.wrap(21);\\n\\n /// @notice Maximum epoch voucher memory range (128 megabytes).\\n Log2Size constant EPOCH_VOUCHER_LOG2_SIZE = Log2Size.wrap(37);\\n\\n /// @notice Maximum epoch notice memory range (128 megabytes).\\n Log2Size constant EPOCH_NOTICE_LOG2_SIZE = Log2Size.wrap(37);\\n\\n /// @notice Unwrap `s` into its underlying uint64 value.\\n /// @param s Base-2 logarithm of some number of bytes\\n function uint64OfSize(Log2Size s) internal pure returns (uint64) {\\n return Log2Size.unwrap(s);\\n }\\n\\n /// @notice Return the position of an 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 Base-2 logarithm of intra memory range size\\n function getIntraMemoryRangePosition(\\n uint64 index,\\n Log2Size log2Size\\n ) internal pure returns (uint64) {\\n return index << Log2Size.unwrap(log2Size);\\n }\\n}\\n\",\"keccak256\":\"0x54a77c72297ee124bb97c691b823dacb8ae427325db1cdeb9416c743accb636b\",\"license\":\"Apache-2.0\"},\"contracts/common/OutputEncoding.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Output Encoding Library\\n///\\n/// @notice Defines the encoding of outputs generated by the off-chain machine.\\nlibrary OutputEncoding {\\n /// @notice Encode a notice.\\n /// @param notice The notice\\n /// @return The encoded output\\n function encodeNotice(\\n bytes calldata notice\\n ) internal pure returns (bytes memory) {\\n return abi.encode(notice);\\n }\\n\\n /// @notice Encode a voucher.\\n /// @param destination The address that will receive the payload through a message call\\n /// @param payload The payload, which\\u2014in the case of Solidity contracts\\u2014encodes a function call\\n /// @return The encoded output\\n function encodeVoucher(\\n address destination,\\n bytes calldata payload\\n ) internal pure returns (bytes memory) {\\n return abi.encode(destination, payload);\\n }\\n}\\n\",\"keccak256\":\"0xc9913f93ac15d2921abae0ec54a2b61a501e26d46a5296d6539aa433bb799246\",\"license\":\"Apache-2.0\"},\"contracts/consensus/IConsensus.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Consensus interface\\n///\\n/// @notice This contract defines a generic interface for consensuses.\\n/// We use the word \\\"consensus\\\" to designate a contract that provides claims\\n/// in the base layer regarding the state of off-chain machines running in\\n/// the execution layer. How this contract is able to reach consensus, who is\\n/// able to submit claims, and how are claims stored in the base layer are\\n/// some of the implementation details left unspecified by this interface.\\n///\\n/// From the point of view of a DApp, these claims are necessary to validate\\n/// on-chain action allowed by the off-chain machine in the form of vouchers\\n/// and notices. Each claim is composed of three parts: an epoch hash, a first\\n/// index, and a last index. We'll explain each of these parts below.\\n///\\n/// First, let us define the word \\\"epoch\\\". For finality reasons, we need to\\n/// divide the stream of inputs being fed into the off-chain machine into\\n/// batches of inputs, which we call \\\"epoches\\\". At the end of every epoch,\\n/// we summarize the state of the off-chain machine in a single hash, called\\n/// \\\"epoch hash\\\". Please note that this interface does not define how this\\n/// stream of inputs is being chopped up into epoches.\\n///\\n/// The other two parts are simply the indices of the first and last inputs\\n/// accepted during the epoch. Logically, the first index MUST BE less than\\n/// or equal to the last index. As a result, every epoch MUST accept at least\\n/// one input. This assumption stems from the fact that the state of a machine\\n/// can only change after an input is fed into it.\\n///\\n/// Examples of possible implementations of this interface include:\\n///\\n/// * An authority consensus, controlled by a single address who has full\\n/// control over epoch boundaries, claim submission, asset management, etc.\\n///\\n/// * A quorum consensus, controlled by a limited set of validators, that\\n/// vote on the state of the machine at the end of every epoch. Also, epoch\\n/// boundaries are determined by the timestamp in the base layer, and assets\\n/// are split equally amongst the validators.\\n///\\n/// * An NxN consensus, which allows anyone to submit and dispute claims\\n/// in the base layer. Epoch boundaries are determined in the same fashion\\n/// as in the quorum example.\\n///\\ninterface IConsensus {\\n /// @notice An application has joined the consensus' validation set.\\n /// @param application The application\\n /// @dev MUST be triggered on a successful call to `join`.\\n event ApplicationJoined(address application);\\n\\n /// @notice Get a specific claim regarding a specific DApp.\\n /// The encoding of `_proofContext` might vary\\n /// depending on the implementation.\\n /// @param _dapp The DApp address\\n /// @param _proofContext Data for retrieving the desired claim\\n /// @return epochHash_ The claimed epoch hash\\n /// @return firstInputIndex_ The index of the first input of the epoch in the input box\\n /// @return lastInputIndex_ The index of the last input of the epoch in the input box\\n function getClaim(\\n address _dapp,\\n bytes calldata _proofContext\\n )\\n external\\n view\\n returns (\\n bytes32 epochHash_,\\n uint256 firstInputIndex_,\\n uint256 lastInputIndex_\\n );\\n\\n /// @notice Signal the consensus that the message sender wants to join its validation set.\\n /// @dev MUST fire an `ApplicationJoined` event with the message sender as argument.\\n function join() external;\\n}\\n\",\"keccak256\":\"0x5d59c8dc3c1483e3173837d679093000077bf175c0b3ad7f02f0ffe611c0a89e\",\"license\":\"Apache-2.0\"},\"contracts/dapp/CartesiDApp.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {ICartesiDApp, Proof} from \\\"./ICartesiDApp.sol\\\";\\nimport {IConsensus} from \\\"../consensus/IConsensus.sol\\\";\\nimport {LibOutputValidation, OutputValidityProof} from \\\"../library/LibOutputValidation.sol\\\";\\nimport {Bitmask} from \\\"@cartesi/util/contracts/Bitmask.sol\\\";\\n\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {ERC721Holder} from \\\"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\\\";\\nimport {ERC1155Holder} from \\\"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol\\\";\\nimport {ReentrancyGuard} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\n/// @title Cartesi DApp\\n///\\n/// @notice This contract acts as the base layer incarnation of a DApp running on the execution layer.\\n/// The DApp is hereby able to interact with other smart contracts through the execution of vouchers\\n/// and the validation of notices. These outputs are generated by the DApp backend on the execution\\n/// layer and can be proven in the base layer thanks to claims submitted by a consensus contract.\\n///\\n/// A voucher is a one-time message call to another contract. It can encode asset transfers, approvals,\\n/// or any other message call that doesn't require Ether to be sent along. A voucher will only be consumed\\n/// if the underlying message call succeeds (that is, it doesn't revert). Furthermore, the return data of\\n/// the message call is discarded entirely. As a protective measure against reentrancy attacks, nested\\n/// voucher executions are prohibited.\\n///\\n/// A notice, on the other hand, constitutes an arbitrary piece of data that can be proven any number of times.\\n/// On their own, they do not trigger any type of contract-to-contract interaction.\\n/// Rather, they merely serve to attest off-chain results, e.g. which player won a particular chess match.\\n///\\n/// Every DApp is subscribed to a consensus contract, and governed by a single address, the owner.\\n/// The consensus has the power of submitting claims, which, in turn, are used to validate vouchers and notices.\\n/// Meanwhile, the owner has complete power over the DApp, as it can replace the consensus at any time.\\n/// Therefore, the users of a DApp must trust both the consensus and the DApp owner.\\n///\\n/// The DApp developer can choose whichever ownership and consensus models it wants.\\n///\\n/// Examples of DApp ownership models include:\\n///\\n/// * no owner (address zero)\\n/// * individual signer (externally-owned account)\\n/// * multiple signers (multi-sig)\\n/// * DAO (decentralized autonomous organization)\\n/// * self-owned DApp (off-chain governance logic)\\n///\\n/// See `IConsensus` for examples of consensus models.\\n///\\n/// This contract inherits the following OpenZeppelin contracts.\\n/// For more information, please consult OpenZeppelin's official documentation.\\n///\\n/// * `Ownable`\\n/// * `ERC721Holder`\\n/// * `ERC1155Holder`\\n/// * `ReentrancyGuard`\\n///\\ncontract CartesiDApp is\\n ICartesiDApp,\\n Ownable,\\n ERC721Holder,\\n ERC1155Holder,\\n ReentrancyGuard\\n{\\n using Bitmask for mapping(uint256 => uint256);\\n using LibOutputValidation for OutputValidityProof;\\n\\n /// @notice The initial machine state hash.\\n /// @dev See the `getTemplateHash` function.\\n bytes32 internal immutable templateHash;\\n\\n /// @notice The executed voucher bitmask, which keeps track of which vouchers\\n /// were executed already in order to avoid re-execution.\\n /// @dev See the `wasVoucherExecuted` function.\\n mapping(uint256 => uint256) internal voucherBitmask;\\n\\n /// @notice The current consensus contract.\\n /// @dev See the `getConsensus` and `migrateToConsensus` functions.\\n IConsensus internal consensus;\\n\\n /// @notice Creates a `CartesiDApp` contract.\\n /// @param _consensus The initial consensus contract\\n /// @param _owner The initial DApp owner\\n /// @param _templateHash The initial machine state hash\\n /// @dev Calls the `join` function on `_consensus`.\\n constructor(IConsensus _consensus, address _owner, bytes32 _templateHash) {\\n transferOwnership(_owner);\\n templateHash = _templateHash;\\n consensus = _consensus;\\n\\n _consensus.join();\\n }\\n\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n Proof calldata _proof\\n ) external override nonReentrant returns (bool) {\\n bytes32 epochHash;\\n uint256 firstInputIndex;\\n uint256 lastInputIndex;\\n uint256 inboxInputIndex;\\n\\n // query the current consensus for the desired claim\\n (epochHash, firstInputIndex, lastInputIndex) = getClaim(_proof.context);\\n\\n // validate the epoch input index and calculate the inbox input index\\n // based on the input index range provided by the consensus\\n inboxInputIndex = _proof.validity.validateInputIndexRange(\\n firstInputIndex,\\n lastInputIndex\\n );\\n\\n // reverts if proof isn't valid\\n _proof.validity.validateVoucher(_destination, _payload, epochHash);\\n\\n uint256 voucherPosition = LibOutputValidation.getBitMaskPosition(\\n _proof.validity.outputIndex,\\n inboxInputIndex\\n );\\n\\n // check if voucher has been executed\\n require(\\n !_wasVoucherExecuted(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 voucherBitmask.setBit(voucherPosition, true);\\n emit VoucherExecuted(voucherPosition);\\n }\\n\\n return succ;\\n }\\n\\n function wasVoucherExecuted(\\n uint256 _inboxInputIndex,\\n uint256 _outputIndex\\n ) external view override returns (bool) {\\n uint256 voucherPosition = LibOutputValidation.getBitMaskPosition(\\n _outputIndex,\\n _inboxInputIndex\\n );\\n return _wasVoucherExecuted(voucherPosition);\\n }\\n\\n function _wasVoucherExecuted(\\n uint256 _voucherPosition\\n ) internal view returns (bool) {\\n return voucherBitmask.getBit(_voucherPosition);\\n }\\n\\n function validateNotice(\\n bytes calldata _notice,\\n Proof calldata _proof\\n ) external view override returns (bool) {\\n bytes32 epochHash;\\n uint256 firstInputIndex;\\n uint256 lastInputIndex;\\n\\n // query the current consensus for the desired claim\\n (epochHash, firstInputIndex, lastInputIndex) = getClaim(_proof.context);\\n\\n // validate the epoch input index based on the input index range\\n // provided by the consensus\\n _proof.validity.validateInputIndexRange(\\n firstInputIndex,\\n lastInputIndex\\n );\\n\\n // reverts if proof isn't valid\\n _proof.validity.validateNotice(_notice, epochHash);\\n\\n return true;\\n }\\n\\n /// @notice Retrieve a claim about the DApp from the current consensus.\\n /// The encoding of `_proofContext` might vary depending on the implementation.\\n /// @param _proofContext Data for retrieving the desired claim\\n /// @return The claimed epoch hash\\n /// @return The index of the first input of the epoch in the input box\\n /// @return The index of the last input of the epoch in the input box\\n function getClaim(\\n bytes calldata _proofContext\\n ) internal view returns (bytes32, uint256, uint256) {\\n return consensus.getClaim(address(this), _proofContext);\\n }\\n\\n function migrateToConsensus(\\n IConsensus _newConsensus\\n ) external override onlyOwner {\\n consensus = _newConsensus;\\n\\n _newConsensus.join();\\n\\n emit NewConsensus(_newConsensus);\\n }\\n\\n function getTemplateHash() external view override returns (bytes32) {\\n return templateHash;\\n }\\n\\n function getConsensus() external view override returns (IConsensus) {\\n return consensus;\\n }\\n\\n /// @notice Accept Ether transfers.\\n /// @dev If you wish to transfer Ether to a DApp while informing\\n /// the DApp backend of it, then please do so through the Ether portal contract.\\n receive() external payable {}\\n\\n /// @notice Transfer some amount of Ether to some recipient.\\n /// @param _receiver The address which will receive the amount of Ether\\n /// @param _value The amount of Ether to be transferred in Wei\\n /// @dev This function can only be called by the DApp itself through vouchers.\\n function withdrawEther(address _receiver, uint256 _value) external {\\n require(msg.sender == address(this), \\\"only itself\\\");\\n (bool sent, ) = _receiver.call{value: _value}(\\\"\\\");\\n require(sent, \\\"withdrawEther failed\\\");\\n }\\n}\\n\",\"keccak256\":\"0x6cebfc76e9bfb887bbc157ce079396ac757fe53156854edbae32f4a0f637baea\",\"license\":\"Apache-2.0\"},\"contracts/dapp/CartesiDAppFactory.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {ICartesiDAppFactory} from \\\"./ICartesiDAppFactory.sol\\\";\\nimport {IConsensus} from \\\"../consensus/IConsensus.sol\\\";\\nimport {CartesiDApp} from \\\"./CartesiDApp.sol\\\";\\n\\n/// @title Cartesi DApp Factory\\n/// @notice Allows anyone to reliably deploy a new `CartesiDApp` contract.\\ncontract CartesiDAppFactory is ICartesiDAppFactory {\\n function newApplication(\\n IConsensus _consensus,\\n address _dappOwner,\\n bytes32 _templateHash\\n ) external override returns (CartesiDApp) {\\n CartesiDApp application = new CartesiDApp(\\n _consensus,\\n _dappOwner,\\n _templateHash\\n );\\n\\n emit ApplicationCreated(\\n _consensus,\\n _dappOwner,\\n _templateHash,\\n application\\n );\\n\\n return application;\\n }\\n\\n function newApplication(\\n IConsensus _consensus,\\n address _dappOwner,\\n bytes32 _templateHash,\\n bytes32 _salt\\n ) external override returns (CartesiDApp) {\\n CartesiDApp application = new CartesiDApp{salt: _salt}(\\n _consensus,\\n _dappOwner,\\n _templateHash\\n );\\n\\n emit ApplicationCreated(\\n _consensus,\\n _dappOwner,\\n _templateHash,\\n application\\n );\\n\\n return application;\\n }\\n\\n function calculateApplicationAddress(\\n IConsensus _consensus,\\n address _dappOwner,\\n bytes32 _templateHash,\\n bytes32 _salt\\n ) external view override returns (address) {\\n return\\n address(\\n uint160(\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(\\n abi.encodePacked(\\n type(CartesiDApp).creationCode,\\n abi.encode(\\n _consensus,\\n _dappOwner,\\n _templateHash\\n )\\n )\\n )\\n )\\n )\\n )\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0xb3677bdae31eab7f6ed08ffa059158b52f1acfdc6c459455fd0f9dc1a71c3097\",\"license\":\"Apache-2.0\"},\"contracts/dapp/ICartesiDApp.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IConsensus} from \\\"../consensus/IConsensus.sol\\\";\\nimport {OutputValidityProof} from \\\"../library/LibOutputValidation.sol\\\";\\n\\n/// @notice Data for validating outputs.\\n/// @param validity A validity proof for the output\\n/// @param context Data for querying the right claim from the current consensus contract\\n/// @dev The encoding of `context` might vary depending on the implementation of the consensus contract.\\nstruct Proof {\\n OutputValidityProof validity;\\n bytes context;\\n}\\n\\n/// @title Cartesi DApp interface\\ninterface ICartesiDApp {\\n // Events\\n\\n /// @notice The DApp has migrated to another consensus contract.\\n /// @param newConsensus The new consensus contract\\n /// @dev MUST be triggered on a successful call to `migrateToConsensus`.\\n event NewConsensus(IConsensus newConsensus);\\n\\n /// @notice A voucher was executed from the DApp.\\n /// @param voucherId A number that uniquely identifies the voucher\\n /// amongst all vouchers emitted by this DApp\\n event VoucherExecuted(uint256 voucherId);\\n\\n // Permissioned functions\\n\\n /// @notice Migrate the DApp to a new consensus.\\n /// @param _newConsensus The new consensus\\n /// @dev Can only be called by the DApp owner.\\n function migrateToConsensus(IConsensus _newConsensus) external;\\n\\n // Permissionless functions\\n\\n /// @notice Try to execute a voucher.\\n ///\\n /// Reverts if voucher was already successfully executed.\\n ///\\n /// @param _destination The address that will receive the payload through a message call\\n /// @param _payload The payload, which\\u2014in the case of Solidity contracts\\u2014encodes a function call\\n /// @param _proof The proof used to validate the voucher against\\n /// a claim submitted by the current consensus contract\\n /// @return Whether the execution was successful or not\\n /// @dev On a successful execution, emits a `VoucherExecuted` event.\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n Proof calldata _proof\\n ) external returns (bool);\\n\\n /// @notice Check whether a voucher has been executed.\\n /// @param _inboxInputIndex The index of the input in the input box\\n /// @param _outputIndex The index of output emitted by the input\\n /// @return Whether the voucher has been executed before\\n function wasVoucherExecuted(\\n uint256 _inboxInputIndex,\\n uint256 _outputIndex\\n ) external view returns (bool);\\n\\n /// @notice Validate a notice.\\n /// @param _notice The notice\\n /// @param _proof Data for validating outputs\\n /// @return Whether the notice is valid or not\\n function validateNotice(\\n bytes calldata _notice,\\n Proof calldata _proof\\n ) external view returns (bool);\\n\\n /// @notice Get the DApp's template hash.\\n /// @return The DApp's template hash\\n function getTemplateHash() external view returns (bytes32);\\n\\n /// @notice Get the current consensus.\\n /// @return The current consensus\\n function getConsensus() external view returns (IConsensus);\\n}\\n\",\"keccak256\":\"0x26998c60612cf3292a41b357c8672e07973a777517b406cdb8231f0219bd0065\",\"license\":\"Apache-2.0\"},\"contracts/dapp/ICartesiDAppFactory.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {CartesiDApp} from \\\"./CartesiDApp.sol\\\";\\nimport {IConsensus} from \\\"../consensus/IConsensus.sol\\\";\\n\\n/// @title Cartesi DApp Factory interface\\ninterface ICartesiDAppFactory {\\n // Events\\n\\n /// @notice A new application was deployed.\\n /// @param consensus The initial consensus contract\\n /// @param dappOwner The initial DApp owner\\n /// @param templateHash The initial machine state hash\\n /// @param application The application\\n /// @dev MUST be triggered on a successful call to `newApplication`.\\n event ApplicationCreated(\\n IConsensus indexed consensus,\\n address dappOwner,\\n bytes32 templateHash,\\n CartesiDApp application\\n );\\n\\n // Permissionless functions\\n\\n /// @notice Deploy a new application.\\n /// @param _consensus The initial consensus contract\\n /// @param _dappOwner The initial DApp owner\\n /// @param _templateHash The initial machine state hash\\n /// @return The application\\n /// @dev On success, MUST emit an `ApplicationCreated` event.\\n function newApplication(\\n IConsensus _consensus,\\n address _dappOwner,\\n bytes32 _templateHash\\n ) external returns (CartesiDApp);\\n\\n /// @notice Deploy a new application deterministically.\\n /// @param _consensus The initial consensus contract\\n /// @param _dappOwner The initial DApp owner\\n /// @param _templateHash The initial machine state hash\\n /// @param _salt The salt used to deterministically generate the DApp address\\n /// @return The application\\n /// @dev On success, MUST emit an `ApplicationCreated` event.\\n function newApplication(\\n IConsensus _consensus,\\n address _dappOwner,\\n bytes32 _templateHash,\\n bytes32 _salt\\n ) external returns (CartesiDApp);\\n\\n /// @notice Calculate the address of an application to be deployed deterministically.\\n /// @param _consensus The initial consensus contract\\n /// @param _dappOwner The initial DApp owner\\n /// @param _templateHash The initial machine state hash\\n /// @param _salt The salt used to deterministically generate the DApp address\\n /// @return The deterministic application address\\n /// @dev Beware that only the `newApplication` function with the `_salt` parameter\\n /// is able to deterministically deploy an application.\\n function calculateApplicationAddress(\\n IConsensus _consensus,\\n address _dappOwner,\\n bytes32 _templateHash,\\n bytes32 _salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x2d4670a60a3deaca24f6def9870bb30fb6077189fa0b91c36cdaaef9d4dc76c8\",\"license\":\"Apache-2.0\"},\"contracts/library/LibOutputValidation.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {CanonicalMachine} from \\\"../common/CanonicalMachine.sol\\\";\\nimport {MerkleV2} from \\\"@cartesi/util/contracts/MerkleV2.sol\\\";\\nimport {OutputEncoding} from \\\"../common/OutputEncoding.sol\\\";\\n\\n/// @param inputIndex Which input, inside the epoch, the output belongs to\\n/// @param outputIndex Index of output emitted by the input\\n/// @param outputHashesRootHash Merkle root of hashes of outputs emitted by the input\\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 uint64 inputIndex;\\n uint64 outputIndex;\\n bytes32 outputHashesRootHash;\\n bytes32 vouchersEpochRootHash;\\n bytes32 noticesEpochRootHash;\\n bytes32 machineStateHash;\\n bytes32[] keccakInHashesSiblings;\\n bytes32[] outputHashesInEpochSiblings;\\n}\\n\\n/// @title Output Validation Library\\nlibrary LibOutputValidation {\\n using CanonicalMachine for CanonicalMachine.Log2Size;\\n\\n /// @notice Make sure the output proof is valid, otherwise revert.\\n /// @param v The output validity proof\\n /// @param encodedOutput The encoded output\\n /// @param epochHash The hash of the epoch in which the output was generated\\n /// @param outputsEpochRootHash Either `v.vouchersEpochRootHash` (for vouchers)\\n /// or `v.noticesEpochRootHash` (for notices)\\n /// @param outputEpochLog2Size Either `EPOCH_VOUCHER_LOG2_SIZE` (for vouchers)\\n /// or `EPOCH_NOTICE_LOG2_SIZE` (for notices)\\n /// @param outputHashesLog2Size Either `VOUCHER_METADATA_LOG2_SIZE` (for vouchers)\\n /// or `NOTICE_METADATA_LOG2_SIZE` (for notices)\\n function validateEncodedOutput(\\n OutputValidityProof calldata v,\\n bytes memory encodedOutput,\\n bytes32 epochHash,\\n bytes32 outputsEpochRootHash,\\n uint256 outputEpochLog2Size,\\n uint256 outputHashesLog2Size\\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 \\\"incorrect epochHash\\\"\\n );\\n\\n // prove that output metadata memory range is contained in epoch's output memory range\\n require(\\n MerkleV2.getRootAfterReplacementInDrive(\\n CanonicalMachine.getIntraMemoryRangePosition(\\n v.inputIndex,\\n CanonicalMachine.KECCAK_LOG2_SIZE\\n ),\\n CanonicalMachine.KECCAK_LOG2_SIZE.uint64OfSize(),\\n outputEpochLog2Size,\\n v.outputHashesRootHash,\\n v.outputHashesInEpochSiblings\\n ) == outputsEpochRootHash,\\n \\\"incorrect outputsEpochRootHash\\\"\\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 = MerkleV2.getMerkleRootFromBytes(\\n abi.encodePacked(keccak256(encodedOutput)),\\n CanonicalMachine.KECCAK_LOG2_SIZE.uint64OfSize()\\n );\\n\\n // prove that Merkle root hash of bytes(hashOfOutput) is contained\\n // in the output metadata array memory range\\n require(\\n MerkleV2.getRootAfterReplacementInDrive(\\n CanonicalMachine.getIntraMemoryRangePosition(\\n v.outputIndex,\\n CanonicalMachine.KECCAK_LOG2_SIZE\\n ),\\n CanonicalMachine.KECCAK_LOG2_SIZE.uint64OfSize(),\\n outputHashesLog2Size,\\n merkleRootOfHashOfOutput,\\n v.keccakInHashesSiblings\\n ) == v.outputHashesRootHash,\\n \\\"incorrect outputHashesRootHash\\\"\\n );\\n }\\n\\n /// @notice Make sure the output proof is valid, otherwise revert.\\n /// @param v The output validity proof\\n /// @param destination The address that will receive the payload through a message call\\n /// @param payload The payload, which\\u2014in the case of Solidity contracts\\u2014encodes a function call\\n /// @param epochHash The hash of the epoch in which the output was generated\\n function validateVoucher(\\n OutputValidityProof calldata v,\\n address destination,\\n bytes calldata payload,\\n bytes32 epochHash\\n ) internal pure {\\n bytes memory encodedVoucher = OutputEncoding.encodeVoucher(\\n destination,\\n payload\\n );\\n validateEncodedOutput(\\n v,\\n encodedVoucher,\\n epochHash,\\n v.vouchersEpochRootHash,\\n CanonicalMachine.EPOCH_VOUCHER_LOG2_SIZE.uint64OfSize(),\\n CanonicalMachine.VOUCHER_METADATA_LOG2_SIZE.uint64OfSize()\\n );\\n }\\n\\n /// @notice Make sure the output proof is valid, otherwise revert.\\n /// @param v The output validity proof\\n /// @param notice The notice\\n /// @param epochHash The hash of the epoch in which the output was generated\\n function validateNotice(\\n OutputValidityProof calldata v,\\n bytes calldata notice,\\n bytes32 epochHash\\n ) internal pure {\\n bytes memory encodedNotice = OutputEncoding.encodeNotice(notice);\\n validateEncodedOutput(\\n v,\\n encodedNotice,\\n epochHash,\\n v.noticesEpochRootHash,\\n CanonicalMachine.EPOCH_NOTICE_LOG2_SIZE.uint64OfSize(),\\n CanonicalMachine.NOTICE_METADATA_LOG2_SIZE.uint64OfSize()\\n );\\n }\\n\\n /// @notice Get the position of a voucher on the bit mask.\\n /// @param voucher The index of voucher from those generated by such input\\n /// @param input The index of the input in the DApp's input box\\n /// @return Position of the voucher on the bit mask\\n function getBitMaskPosition(\\n uint256 voucher,\\n uint256 input\\n ) internal pure returns (uint256) {\\n // voucher * 2 ** 128 + input\\n // this shouldn't overflow because it is impossible to have > 2**128 vouchers\\n // and because we are assuming there will be < 2 ** 128 inputs on the input box\\n return (((voucher << 128) | input));\\n }\\n\\n /// @notice Validate input index range and get the inbox input index.\\n /// @param v The output validity proof\\n /// @param firstInputIndex The index of the first input of the epoch in the input box\\n /// @param lastInputIndex The index of the last input of the epoch in the input box\\n /// @return The index of the input in the DApp's input box\\n /// @dev Reverts if epoch input index is not compatible with the provided input index range.\\n function validateInputIndexRange(\\n OutputValidityProof calldata v,\\n uint256 firstInputIndex,\\n uint256 lastInputIndex\\n ) internal pure returns (uint256) {\\n uint256 inboxInputIndex = firstInputIndex + v.inputIndex;\\n\\n require(\\n inboxInputIndex <= lastInputIndex,\\n \\\"inbox input index out of bounds\\\"\\n );\\n\\n return inboxInputIndex;\\n }\\n}\\n\",\"keccak256\":\"0x550beda17443b800aa1754861c2b3865c5ce7e71c7597ef93c7ec35aa1022fb0\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611c3c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630e1a07f5146100465780633648bfb514610075578063bd4f121914610088575b600080fd5b6100596100543660046102fe565b61009b565b6040516001600160a01b03909116815260200160405180910390f35b610059610083366004610344565b610148565b6100596100963660046102fe565b6101ef565b600080828686866040516100ae906102d9565b6001600160a01b03938416815292909116602083015260408201526060018190604051809103906000f59050801580156100ec573d6000803e3d6000fd5b50604080516001600160a01b03888116825260208201889052838116828401529151929350908816917fe73165c2d277daf8713fd08b40845cb6bb7a20b2b543f3d35324a475660fcebd9181900360600190a295945050505050565b60008084848460405161015a906102d9565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f080158015610194573d6000803e3d6000fd5b50604080516001600160a01b03878116825260208201879052838116828401529151929350908716917fe73165c2d277daf8713fd08b40845cb6bb7a20b2b543f3d35324a475660fcebd9181900360600190a2949350505050565b600060ff60f81b308360405180602001610208906102d9565b601f1982820381018352601f9091011660408181526001600160a01b038b811660208401528a16908201526060810188905260800160408051601f198184030181529082905261025b92916020016103b5565b604051602081830303815290604052805190602001206040516020016102b894939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012095945050505050565b611834806103d383390190565b6001600160a01b03811681146102fb57600080fd5b50565b6000806000806080858703121561031457600080fd5b843561031f816102e6565b9350602085013561032f816102e6565b93969395505050506040820135916060013590565b60008060006060848603121561035957600080fd5b8335610364816102e6565b92506020840135610374816102e6565b929592945050506040919091013590565b6000815160005b818110156103a6576020818501810151868301520161038c565b50600093019283525090919050565b60006103ca6103c48386610385565b84610385565b94935050505056fe60a06040523480156200001157600080fd5b506040516200183438038062001834833981016040819052620000349162000212565b6200003f33620000cb565b600180556200004e826200011b565b6080819052600380546001600160a01b0319166001600160a01b0385169081179091556040805163b688a36360e01b8152905163b688a3639160048082019260009290919082900301818387803b158015620000a957600080fd5b505af1158015620000be573d6000803e3d6000fd5b505050505050506200025a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620001256200019e565b6001600160a01b038116620001905760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6200019b81620000cb565b50565b6000546001600160a01b03163314620001fa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000187565b565b6001600160a01b03811681146200019b57600080fd5b6000806000606084860312156200022857600080fd5b83516200023581620001fc565b60208501519093506200024881620001fc565b80925050604084015190509250925092565b6080516115be6200027660003960006101ec01526115be6000f3fe6080604052600436106100e15760003560e01c80638da5cb5b1161007f578063bc197c8111610059578063bc197c8114610288578063f23a6e61146102b4578063f2fde38b146102e0578063fc4116831461030057600080fd5b80638da5cb5b1461022a57806396487d46146102485780639d9b11451461026857600080fd5b8063179e740b116100bb578063179e740b14610186578063522f6815146101b857806361b12c66146101da578063715018a61461021557600080fd5b806301ffc9a7146100ed5780631250482f14610122578063150b7a021461014257600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d610108366004610e4e565b610320565b60405190151581526020015b60405180910390f35b34801561012e57600080fd5b5061010d61013d366004610ef4565b610357565b34801561014e57600080fd5b5061016d61015d366004611024565b630a85bd0160e11b949350505050565b6040516001600160e01b03199091168152602001610119565b34801561019257600080fd5b506003546001600160a01b03165b6040516001600160a01b039091168152602001610119565b3480156101c457600080fd5b506101d86101d3366004611083565b610570565b005b3480156101e657600080fd5b506040517f00000000000000000000000000000000000000000000000000000000000000008152602001610119565b34801561022157600080fd5b506101d861064c565b34801561023657600080fd5b506000546001600160a01b03166101a0565b34801561025457600080fd5b5061010d6102633660046110af565b610660565b34801561027457600080fd5b5061010d610283366004611117565b6106b1565b34801561029457600080fd5b5061016d6102a33660046111b8565b63bc197c8160e01b95945050505050565b3480156102c057600080fd5b5061016d6102cf366004611265565b63f23a6e6160e01b95945050505050565b3480156102ec57600080fd5b506101d86102fb3660046112cd565b6106c3565b34801561030c57600080fd5b506101d861031b3660046112cd565b61073c565b60006001600160e01b03198216630271189760e51b148061035157506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006103616107f1565b600080808061037b61037660208801886112ea565b61084a565b9195509350915061039883836103918980611330565b91906108d1565b90506103b4898989876103ab8b80611330565b93929190610946565b60006103e86103c38880611330565b6103d4906040810190602001611350565b6001600160401b03168360809190911b1790565b90506103f38161097b565b156104455760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f776564000000000000000060448201526064015b60405180910390fd5b60008a6001600160a01b03168a8a604051610461929190611379565b6000604051808303816000865af19150503d806000811461049e576040519150601f19603f3d011682016040523d82523d6000602084013e6104a3565b606091505b505090508015610558576040516306449da160e41b8152600260048201526024810183905260016044820152730165878A594ca255338adfa4d48449f69242Eb8F90636449da109060640160006040518083038186803b15801561050657600080fd5b505af415801561051a573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc548260405161054f91815260200190565b60405180910390a15b9550505050505061056860018055565b949350505050565b3330146105ad5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b604482015260640161043c565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146105fa576040519150601f19603f3d011682016040523d82523d6000602084013e6105ff565b606091505b50509050806106475760405162461bcd60e51b81526020600482015260146024820152731dda5d1a191c985dd15d1a195c8819985a5b195960621b604482015260640161043c565b505050565b6106546109f9565b61065e6000610a53565b565b600080808061067561037660208701876112ea565b9194509250905061068b82826103918880611330565b506106a487878561069c8980611330565b929190610aa3565b5060019695505050505050565b6000608082901b83176105688161097b565b6106cb6109f9565b6001600160a01b0381166107305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161043c565b61073981610a53565b50565b6107446109f9565b600380546001600160a01b0319166001600160a01b0383169081179091556040805163b688a36360e01b8152905163b688a3639160048082019260009290919082900301818387803b15801561079957600080fd5b505af11580156107ad573d6000803e3d6000fd5b50506040516001600160a01b03841681527f4991c6f37185659e276ff918a96f3e20e6c5abcd8c9aab450dc19c2f7ad35cb59250602001905060405180910390a150565b6002600154036108435760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161043c565b6002600155565b60035460405163035e6a0960e61b8152600091829182916001600160a01b03169063d79a824090610883903090899089906004016113b2565b606060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c491906113e0565b9250925092509250925092565b6000806108e16020860186611350565b6108f4906001600160401b03168561140e565b9050828111156105685760405162461bcd60e51b815260206004820152601f60248201527f696e626f7820696e70757420696e646578206f7574206f6620626f756e647300604482015260640161043c565b6000610953858585610aca565b9050610973868284606083013560255b6001600160401b03166015610af9565b505050505050565b6040516303fbaf7360e01b81526002600482015260248101829052600090730165878A594ca255338adfa4d48449f69242Eb8F906303fbaf7390604401602060405180830381865af41580156109d5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610351919061142f565b6000546001600160a01b0316331461065e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161043c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000610aaf8484610e22565b9050610ac385828460808301356025610963565b5050505050565b6060838383604051602001610ae1939291906113b2565b60405160208183030381529060405290509392505050565b6040805160608089013560208301526080808a01359383019390935260a0890135908201528591016040516020818303038152906040528051906020012014610b7a5760405162461bcd60e51b81526020600482015260136024820152720d2dcc6dee4e4cac6e840cae0dec6d090c2e6d606b1b604482015260640161043c565b82732279B7A0a67DB372996a5FaB50D91eAA73d2eBe66379de4601610bb6610ba560208b018b611350565b60051b681fffffffffffffffe01690565b60058660408c0135610bcb60e08e018e611451565b6040518763ffffffff1660e01b8152600401610bec9695949392919061149a565b602060405180830381865af4158015610c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2d91906114fd565b14610c7a5760405162461bcd60e51b815260206004820152601e60248201527f696e636f7272656374206f75747075747345706f6368526f6f74486173680000604482015260640161043c565b6000732279B7A0a67DB372996a5FaB50D91eAA73d2eBe663c84583a18780519060200120604051602001610cb091815260200190565b60408051601f19818403018152908290526001600160e01b031960e084901b168252610ce191600590600401611516565b602060405180830381865af4158015610cfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2291906114fd565b90508660400135732279B7A0a67DB372996a5FaB50D91eAA73d2eBe66379de4601610d598a6020016020810190610ba59190611350565b60058686610d6a60c08f018f611451565b6040518763ffffffff1660e01b8152600401610d8b9695949392919061149a565b602060405180830381865af4158015610da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcc91906114fd565b14610e195760405162461bcd60e51b815260206004820152601e60248201527f696e636f7272656374206f7574707574486173686573526f6f74486173680000604482015260640161043c565b50505050505050565b60608282604051602001610e37929190611574565b604051602081830303815290604052905092915050565b600060208284031215610e6057600080fd5b81356001600160e01b031981168114610e7857600080fd5b9392505050565b6001600160a01b038116811461073957600080fd5b60008083601f840112610ea657600080fd5b5081356001600160401b03811115610ebd57600080fd5b602083019150836020828501011115610ed557600080fd5b9250929050565b600060408284031215610eee57600080fd5b50919050565b60008060008060608587031215610f0a57600080fd5b8435610f1581610e7f565b935060208501356001600160401b0380821115610f3157600080fd5b610f3d88838901610e94565b90955093506040870135915080821115610f5657600080fd5b50610f6387828801610edc565b91505092959194509250565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610fad57610fad610f6f565b604052919050565b600082601f830112610fc657600080fd5b81356001600160401b03811115610fdf57610fdf610f6f565b610ff2601f8201601f1916602001610f85565b81815284602083860101111561100757600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561103a57600080fd5b843561104581610e7f565b9350602085013561105581610e7f565b92506040850135915060608501356001600160401b0381111561107757600080fd5b610f6387828801610fb5565b6000806040838503121561109657600080fd5b82356110a181610e7f565b946020939093013593505050565b6000806000604084860312156110c457600080fd5b83356001600160401b03808211156110db57600080fd5b6110e787838801610e94565b9095509350602086013591508082111561110057600080fd5b5061110d86828701610edc565b9150509250925092565b6000806040838503121561112a57600080fd5b50508035926020909101359150565b600082601f83011261114a57600080fd5b813560206001600160401b0382111561116557611165610f6f565b8160051b611174828201610f85565b928352848101820192828101908785111561118e57600080fd5b83870192505b848310156111ad57823582529183019190830190611194565b979650505050505050565b600080600080600060a086880312156111d057600080fd5b85356111db81610e7f565b945060208601356111eb81610e7f565b935060408601356001600160401b038082111561120757600080fd5b61121389838a01611139565b9450606088013591508082111561122957600080fd5b61123589838a01611139565b9350608088013591508082111561124b57600080fd5b5061125888828901610fb5565b9150509295509295909350565b600080600080600060a0868803121561127d57600080fd5b853561128881610e7f565b9450602086013561129881610e7f565b9350604086013592506060860135915060808601356001600160401b038111156112c157600080fd5b61125888828901610fb5565b6000602082840312156112df57600080fd5b8135610e7881610e7f565b6000808335601e1984360301811261130157600080fd5b8301803591506001600160401b0382111561131b57600080fd5b602001915036819003821315610ed557600080fd5b6000823560fe1983360301811261134657600080fd5b9190910192915050565b60006020828403121561136257600080fd5b81356001600160401b0381168114610e7857600080fd5b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03841681526040602082018190526000906113d79083018486611389565b95945050505050565b6000806000606084860312156113f557600080fd5b8351925060208401519150604084015190509250925092565b8082018082111561035157634e487b7160e01b600052601160045260246000fd5b60006020828403121561144157600080fd5b81518015158114610e7857600080fd5b6000808335601e1984360301811261146857600080fd5b8301803591506001600160401b0382111561148257600080fd5b6020019150600581901b3603821315610ed557600080fd5b6001600160401b03878116825286166020820152604081018590526060810184905260a060808201819052810182905260006001600160fb1b038311156114e057600080fd5b8260051b808560c08501379190910160c001979650505050505050565b60006020828403121561150f57600080fd5b5051919050565b604081526000835180604084015260005b818110156115445760208187018101516060868401015201611527565b506000606082850101526060601f19601f8301168401019150506001600160401b03831660208301529392505050565b60208152600061056860208301848661138956fea26469706673582212208f9e8048a97915b9b103dd5e284d2d7669007c53303a0c3606f635e78fa28b6c64736f6c63430008130033a2646970667358221220a59be7bf53f8cadfa77840df77f3a27364b66a5d1e961f3bbdb5838547c69e8564736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80630e1a07f5146100465780633648bfb514610075578063bd4f121914610088575b600080fd5b6100596100543660046102fe565b61009b565b6040516001600160a01b03909116815260200160405180910390f35b610059610083366004610344565b610148565b6100596100963660046102fe565b6101ef565b600080828686866040516100ae906102d9565b6001600160a01b03938416815292909116602083015260408201526060018190604051809103906000f59050801580156100ec573d6000803e3d6000fd5b50604080516001600160a01b03888116825260208201889052838116828401529151929350908816917fe73165c2d277daf8713fd08b40845cb6bb7a20b2b543f3d35324a475660fcebd9181900360600190a295945050505050565b60008084848460405161015a906102d9565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f080158015610194573d6000803e3d6000fd5b50604080516001600160a01b03878116825260208201879052838116828401529151929350908716917fe73165c2d277daf8713fd08b40845cb6bb7a20b2b543f3d35324a475660fcebd9181900360600190a2949350505050565b600060ff60f81b308360405180602001610208906102d9565b601f1982820381018352601f9091011660408181526001600160a01b038b811660208401528a16908201526060810188905260800160408051601f198184030181529082905261025b92916020016103b5565b604051602081830303815290604052805190602001206040516020016102b894939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012095945050505050565b611834806103d383390190565b6001600160a01b03811681146102fb57600080fd5b50565b6000806000806080858703121561031457600080fd5b843561031f816102e6565b9350602085013561032f816102e6565b93969395505050506040820135916060013590565b60008060006060848603121561035957600080fd5b8335610364816102e6565b92506020840135610374816102e6565b929592945050506040919091013590565b6000815160005b818110156103a6576020818501810151868301520161038c565b50600093019283525090919050565b60006103ca6103c48386610385565b84610385565b94935050505056fe60a06040523480156200001157600080fd5b506040516200183438038062001834833981016040819052620000349162000212565b6200003f33620000cb565b600180556200004e826200011b565b6080819052600380546001600160a01b0319166001600160a01b0385169081179091556040805163b688a36360e01b8152905163b688a3639160048082019260009290919082900301818387803b158015620000a957600080fd5b505af1158015620000be573d6000803e3d6000fd5b505050505050506200025a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620001256200019e565b6001600160a01b038116620001905760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6200019b81620000cb565b50565b6000546001600160a01b03163314620001fa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000187565b565b6001600160a01b03811681146200019b57600080fd5b6000806000606084860312156200022857600080fd5b83516200023581620001fc565b60208501519093506200024881620001fc565b80925050604084015190509250925092565b6080516115be6200027660003960006101ec01526115be6000f3fe6080604052600436106100e15760003560e01c80638da5cb5b1161007f578063bc197c8111610059578063bc197c8114610288578063f23a6e61146102b4578063f2fde38b146102e0578063fc4116831461030057600080fd5b80638da5cb5b1461022a57806396487d46146102485780639d9b11451461026857600080fd5b8063179e740b116100bb578063179e740b14610186578063522f6815146101b857806361b12c66146101da578063715018a61461021557600080fd5b806301ffc9a7146100ed5780631250482f14610122578063150b7a021461014257600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d610108366004610e4e565b610320565b60405190151581526020015b60405180910390f35b34801561012e57600080fd5b5061010d61013d366004610ef4565b610357565b34801561014e57600080fd5b5061016d61015d366004611024565b630a85bd0160e11b949350505050565b6040516001600160e01b03199091168152602001610119565b34801561019257600080fd5b506003546001600160a01b03165b6040516001600160a01b039091168152602001610119565b3480156101c457600080fd5b506101d86101d3366004611083565b610570565b005b3480156101e657600080fd5b506040517f00000000000000000000000000000000000000000000000000000000000000008152602001610119565b34801561022157600080fd5b506101d861064c565b34801561023657600080fd5b506000546001600160a01b03166101a0565b34801561025457600080fd5b5061010d6102633660046110af565b610660565b34801561027457600080fd5b5061010d610283366004611117565b6106b1565b34801561029457600080fd5b5061016d6102a33660046111b8565b63bc197c8160e01b95945050505050565b3480156102c057600080fd5b5061016d6102cf366004611265565b63f23a6e6160e01b95945050505050565b3480156102ec57600080fd5b506101d86102fb3660046112cd565b6106c3565b34801561030c57600080fd5b506101d861031b3660046112cd565b61073c565b60006001600160e01b03198216630271189760e51b148061035157506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006103616107f1565b600080808061037b61037660208801886112ea565b61084a565b9195509350915061039883836103918980611330565b91906108d1565b90506103b4898989876103ab8b80611330565b93929190610946565b60006103e86103c38880611330565b6103d4906040810190602001611350565b6001600160401b03168360809190911b1790565b90506103f38161097b565b156104455760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f776564000000000000000060448201526064015b60405180910390fd5b60008a6001600160a01b03168a8a604051610461929190611379565b6000604051808303816000865af19150503d806000811461049e576040519150601f19603f3d011682016040523d82523d6000602084013e6104a3565b606091505b505090508015610558576040516306449da160e41b815260026004820152602481018390526001604482015273__$f57eb21c11c6dae369da3ca36f4f48eb77$__90636449da109060640160006040518083038186803b15801561050657600080fd5b505af415801561051a573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc548260405161054f91815260200190565b60405180910390a15b9550505050505061056860018055565b949350505050565b3330146105ad5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b604482015260640161043c565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146105fa576040519150601f19603f3d011682016040523d82523d6000602084013e6105ff565b606091505b50509050806106475760405162461bcd60e51b81526020600482015260146024820152731dda5d1a191c985dd15d1a195c8819985a5b195960621b604482015260640161043c565b505050565b6106546109f9565b61065e6000610a53565b565b600080808061067561037660208701876112ea565b9194509250905061068b82826103918880611330565b506106a487878561069c8980611330565b929190610aa3565b5060019695505050505050565b6000608082901b83176105688161097b565b6106cb6109f9565b6001600160a01b0381166107305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161043c565b61073981610a53565b50565b6107446109f9565b600380546001600160a01b0319166001600160a01b0383169081179091556040805163b688a36360e01b8152905163b688a3639160048082019260009290919082900301818387803b15801561079957600080fd5b505af11580156107ad573d6000803e3d6000fd5b50506040516001600160a01b03841681527f4991c6f37185659e276ff918a96f3e20e6c5abcd8c9aab450dc19c2f7ad35cb59250602001905060405180910390a150565b6002600154036108435760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161043c565b6002600155565b60035460405163035e6a0960e61b8152600091829182916001600160a01b03169063d79a824090610883903090899089906004016113b2565b606060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c491906113e0565b9250925092509250925092565b6000806108e16020860186611350565b6108f4906001600160401b03168561140e565b9050828111156105685760405162461bcd60e51b815260206004820152601f60248201527f696e626f7820696e70757420696e646578206f7574206f6620626f756e647300604482015260640161043c565b6000610953858585610aca565b9050610973868284606083013560255b6001600160401b03166015610af9565b505050505050565b6040516303fbaf7360e01b8152600260048201526024810182905260009073__$f57eb21c11c6dae369da3ca36f4f48eb77$__906303fbaf7390604401602060405180830381865af41580156109d5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610351919061142f565b6000546001600160a01b0316331461065e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161043c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000610aaf8484610e22565b9050610ac385828460808301356025610963565b5050505050565b6060838383604051602001610ae1939291906113b2565b60405160208183030381529060405290509392505050565b6040805160608089013560208301526080808a01359383019390935260a0890135908201528591016040516020818303038152906040528051906020012014610b7a5760405162461bcd60e51b81526020600482015260136024820152720d2dcc6dee4e4cac6e840cae0dec6d090c2e6d606b1b604482015260640161043c565b8273__$2a7ef22e717e9afc55afc95d018bf1a85b$__6379de4601610bb6610ba560208b018b611350565b60051b681fffffffffffffffe01690565b60058660408c0135610bcb60e08e018e611451565b6040518763ffffffff1660e01b8152600401610bec9695949392919061149a565b602060405180830381865af4158015610c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2d91906114fd565b14610c7a5760405162461bcd60e51b815260206004820152601e60248201527f696e636f7272656374206f75747075747345706f6368526f6f74486173680000604482015260640161043c565b600073__$2a7ef22e717e9afc55afc95d018bf1a85b$__63c84583a18780519060200120604051602001610cb091815260200190565b60408051601f19818403018152908290526001600160e01b031960e084901b168252610ce191600590600401611516565b602060405180830381865af4158015610cfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2291906114fd565b9050866040013573__$2a7ef22e717e9afc55afc95d018bf1a85b$__6379de4601610d598a6020016020810190610ba59190611350565b60058686610d6a60c08f018f611451565b6040518763ffffffff1660e01b8152600401610d8b9695949392919061149a565b602060405180830381865af4158015610da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcc91906114fd565b14610e195760405162461bcd60e51b815260206004820152601e60248201527f696e636f7272656374206f7574707574486173686573526f6f74486173680000604482015260640161043c565b50505050505050565b60608282604051602001610e37929190611574565b604051602081830303815290604052905092915050565b600060208284031215610e6057600080fd5b81356001600160e01b031981168114610e7857600080fd5b9392505050565b6001600160a01b038116811461073957600080fd5b60008083601f840112610ea657600080fd5b5081356001600160401b03811115610ebd57600080fd5b602083019150836020828501011115610ed557600080fd5b9250929050565b600060408284031215610eee57600080fd5b50919050565b60008060008060608587031215610f0a57600080fd5b8435610f1581610e7f565b935060208501356001600160401b0380821115610f3157600080fd5b610f3d88838901610e94565b90955093506040870135915080821115610f5657600080fd5b50610f6387828801610edc565b91505092959194509250565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610fad57610fad610f6f565b604052919050565b600082601f830112610fc657600080fd5b81356001600160401b03811115610fdf57610fdf610f6f565b610ff2601f8201601f1916602001610f85565b81815284602083860101111561100757600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561103a57600080fd5b843561104581610e7f565b9350602085013561105581610e7f565b92506040850135915060608501356001600160401b0381111561107757600080fd5b610f6387828801610fb5565b6000806040838503121561109657600080fd5b82356110a181610e7f565b946020939093013593505050565b6000806000604084860312156110c457600080fd5b83356001600160401b03808211156110db57600080fd5b6110e787838801610e94565b9095509350602086013591508082111561110057600080fd5b5061110d86828701610edc565b9150509250925092565b6000806040838503121561112a57600080fd5b50508035926020909101359150565b600082601f83011261114a57600080fd5b813560206001600160401b0382111561116557611165610f6f565b8160051b611174828201610f85565b928352848101820192828101908785111561118e57600080fd5b83870192505b848310156111ad57823582529183019190830190611194565b979650505050505050565b600080600080600060a086880312156111d057600080fd5b85356111db81610e7f565b945060208601356111eb81610e7f565b935060408601356001600160401b038082111561120757600080fd5b61121389838a01611139565b9450606088013591508082111561122957600080fd5b61123589838a01611139565b9350608088013591508082111561124b57600080fd5b5061125888828901610fb5565b9150509295509295909350565b600080600080600060a0868803121561127d57600080fd5b853561128881610e7f565b9450602086013561129881610e7f565b9350604086013592506060860135915060808601356001600160401b038111156112c157600080fd5b61125888828901610fb5565b6000602082840312156112df57600080fd5b8135610e7881610e7f565b6000808335601e1984360301811261130157600080fd5b8301803591506001600160401b0382111561131b57600080fd5b602001915036819003821315610ed557600080fd5b6000823560fe1983360301811261134657600080fd5b9190910192915050565b60006020828403121561136257600080fd5b81356001600160401b0381168114610e7857600080fd5b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03841681526040602082018190526000906113d79083018486611389565b95945050505050565b6000806000606084860312156113f557600080fd5b8351925060208401519150604084015190509250925092565b8082018082111561035157634e487b7160e01b600052601160045260246000fd5b60006020828403121561144157600080fd5b81518015158114610e7857600080fd5b6000808335601e1984360301811261146857600080fd5b8301803591506001600160401b0382111561148257600080fd5b6020019150600581901b3603821315610ed557600080fd5b6001600160401b03878116825286166020820152604081018590526060810184905260a060808201819052810182905260006001600160fb1b038311156114e057600080fd5b8260051b808560c08501379190910160c001979650505050505050565b60006020828403121561150f57600080fd5b5051919050565b604081526000835180604084015260005b818110156115445760208187018101516060868401015201611527565b506000606082850101526060601f19601f8301168401019150506001600160401b03831660208301529392505050565b60208152600061056860208301848661138956fea26469706673582212208f9e8048a97915b9b103dd5e284d2d7669007c53303a0c3606f635e78fa28b6c64736f6c63430008130033a2646970667358221220a59be7bf53f8cadfa77840df77f3a27364b66a5d1e961f3bbdb5838547c69e8564736f6c63430008130033", + "libraries": { + "Bitmask": "0x0165878A594ca255338adfa4d48449f69242Eb8F", + "MerkleV2": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + }, "devdoc": { + "events": { + "ApplicationCreated(address,address,bytes32,address)": { + "details": "MUST be triggered on a successful call to `newApplication`.", + "params": { + "application": "The application", + "consensus": "The initial consensus contract", + "dappOwner": "The initial DApp owner", + "templateHash": "The initial machine state hash" + } + } + }, "kind": "dev", "methods": { - "newApplication((address,bytes32,uint256,uint256,uint256,uint256,address,address[]))": { + "calculateApplicationAddress(address,address,bytes32,bytes32)": { + "details": "Beware that only the `newApplication` function with the `_salt` parameter is able to deterministically deploy an application.", "params": { - "_appConfig": "application configurations" + "_consensus": "The initial consensus contract", + "_dappOwner": "The initial DApp owner", + "_salt": "The salt used to deterministically generate the DApp address", + "_templateHash": "The initial machine state hash" }, "returns": { - "_0": "application address" + "_0": "The deterministic application address" + } + }, + "newApplication(address,address,bytes32)": { + "details": "On success, MUST emit an `ApplicationCreated` event.", + "params": { + "_consensus": "The initial consensus contract", + "_dappOwner": "The initial DApp owner", + "_templateHash": "The initial machine state hash" + }, + "returns": { + "_0": "The application" + } + }, + "newApplication(address,address,bytes32,bytes32)": { + "details": "On success, MUST emit an `ApplicationCreated` event.", + "params": { + "_consensus": "The initial consensus contract", + "_dappOwner": "The initial DApp owner", + "_salt": "The salt used to deterministically generate the DApp address", + "_templateHash": "The initial machine state hash" + }, + "returns": { + "_0": "The application" } } }, + "title": "Cartesi DApp Factory", "version": 1 }, "userdoc": { "events": { - "ApplicationCreated(address,(address,bytes32,uint256,uint256,uint256,uint256,address,address[]))": { - "notice": "Event emitted when a new application is deployed" + "ApplicationCreated(address,address,bytes32,address)": { + "notice": "A new application was deployed." } }, "kind": "user", "methods": { - "newApplication((address,bytes32,uint256,uint256,uint256,uint256,address,address[]))": { - "notice": "Deploy a new application" + "calculateApplicationAddress(address,address,bytes32,bytes32)": { + "notice": "Calculate the address of an application to be deployed deterministically." + }, + "newApplication(address,address,bytes32)": { + "notice": "Deploy a new application." + }, + "newApplication(address,address,bytes32,bytes32)": { + "notice": "Deploy a new application deterministically." } }, + "notice": "Allows anyone to reliably deploy a new `CartesiDApp` contract.", "version": 1 }, "storageLayout": { - "storage": [ - { - "astId": 3751, - "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", - "label": "diamondCut", - "offset": 0, - "slot": "0", - "type": "t_array(t_struct(FacetCut)6868_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)6868_storage)dyn_storage": { - "base": "t_struct(FacetCut)6868_storage", - "encoding": "dynamic_array", - "label": "struct IDiamondCut.FacetCut[]", - "numberOfBytes": "32" - }, - "t_bytes4": { - "encoding": "inplace", - "label": "bytes4", - "numberOfBytes": "4" - }, - "t_enum(FacetCutAction)6859": { - "encoding": "inplace", - "label": "enum IDiamondCut.FacetCutAction", - "numberOfBytes": "1" - }, - "t_struct(FacetCut)6868_storage": { - "encoding": "inplace", - "label": "struct IDiamondCut.FacetCut", - "members": [ - { - "astId": 6861, - "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", - "label": "facetAddress", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 6864, - "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", - "label": "action", - "offset": 20, - "slot": "0", - "type": "t_enum(FacetCutAction)6859" - }, - { - "astId": 6867, - "contract": "contracts/CartesiDAppFactory.sol:CartesiDAppFactory", - "label": "functionSelectors", - "offset": 0, - "slot": "1", - "type": "t_array(t_bytes4)dyn_storage" - } - ], - "numberOfBytes": "64" - } - } + "storage": [], + "types": null } } \ No newline at end of file diff --git a/deployments/localhost/CartesiMathV2.json b/deployments/localhost/CartesiMathV2.json index 76260f4..7c06d1d 100644 --- a/deployments/localhost/CartesiMathV2.json +++ b/deployments/localhost/CartesiMathV2.json @@ -116,19 +116,19 @@ "type": "function" } ], - "transactionHash": "0xee179df935ff0c8440de16ff0ffd0e724de4fb4682aead8a8331fd3e6724060a", + "transactionHash": "0x4fed090bac15fd34dc7a68b0699b6aca8a0168c1991dc24f8344b54dda61d19c", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", "transactionIndex": 0, - "gasUsed": "493935", + "gasUsed": "494067", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xff2d63f21989e998929484af0ca367467e1fc18a96e2b865e28fec4a86b46439", - "transactionHash": "0xee179df935ff0c8440de16ff0ffd0e724de4fb4682aead8a8331fd3e6724060a", + "blockHash": "0xd5f8402389e2c44af1444bfabb59b88b3b414d8a2b366bc2c1c2ccd73aea92da", + "transactionHash": "0x4fed090bac15fd34dc7a68b0699b6aca8a0168c1991dc24f8344b54dda61d19c", "logs": [], "blockNumber": 8, - "cumulativeGasUsed": "493935", + "cumulativeGasUsed": "494067", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/CartesiToken.json b/deployments/localhost/CartesiToken.json deleted file mode 100644 index 9ffcbec..0000000 --- a/deployments/localhost/CartesiToken.json +++ /dev/null @@ -1,536 +0,0 @@ -{ - "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "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": "0xb84e1d8372547141b4e8fb9ebfb7a39ed43aa276ddb003bbcce12dba5db85362", - "receipt": { - "to": null, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "transactionIndex": 0, - "gasUsed": "1770294", - "logsBloom": "0x00800000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000040000000000020000000000000000020000000000000100000800000000008000000040000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000200000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfd9a12447b702d788ad5f32a81b8b37002efca20e2500e946995b58691a0f84b", - "transactionHash": "0xb84e1d8372547141b4e8fb9ebfb7a39ed43aa276ddb003bbcce12dba5db85362", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 11, - "transactionHash": "0xb84e1d8372547141b4e8fb9ebfb7a39ed43aa276ddb003bbcce12dba5db85362", - "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "topics": [ - "0x6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f6", - "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0xfd9a12447b702d788ad5f32a81b8b37002efca20e2500e946995b58691a0f84b" - }, - { - "transactionIndex": 0, - "blockNumber": 11, - "transactionHash": "0xb84e1d8372547141b4e8fb9ebfb7a39ed43aa276ddb003bbcce12dba5db85362", - "address": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" - ], - "data": "0x0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000", - "logIndex": 1, - "blockHash": "0xfd9a12447b702d788ad5f32a81b8b37002efca20e2500e946995b58691a0f84b" - } - ], - "blockNumber": 11, - "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/deployments/localhost/DAppAddressRelay.json b/deployments/localhost/DAppAddressRelay.json new file mode 100644 index 0000000..88b101b --- /dev/null +++ b/deployments/localhost/DAppAddressRelay.json @@ -0,0 +1,108 @@ +{ + "address": "0x8Bbc0e6daB541DF0A9f0bDdA5D41B3B08B081d55", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IInputBox", + "name": "_inputBox", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "getInputBox", + "outputs": [ + { + "internalType": "contract IInputBox", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dapp", + "type": "address" + } + ], + "name": "relayDAppAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xb51aa21941fa38e9f0b3a2aa5822e03073ea627d9650d4b2a11069c1301df251", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "175472", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2bb2fa3b88203df738aeed7d12f3e9e53af6912871dc22e833a1fb44fee77b70", + "transactionHash": "0xb51aa21941fa38e9f0b3a2aa5822e03073ea627d9650d4b2a11069c1301df251", + "logs": [], + "blockNumber": 17, + "cumulativeGasUsed": "175472", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5a723220579C0DCb8C9253E6b4c62e572E379945" + ], + "numDeployments": 1, + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"_inputBox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"getInputBox\",\"outputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"}],\"name\":\"relayDAppAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_inputBox\":\"The input box used by the relay\"}},\"getInputBox()\":{\"returns\":{\"_0\":\"The input box\"}},\"relayDAppAddress(address)\":{\"params\":{\"_dapp\":\"The address of the DApp\"}}},\"title\":\"DApp Address Relay\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructs the relay.\"},\"getInputBox()\":{\"notice\":\"Get the input box used by this relay.\"},\"relayDAppAddress(address)\":{\"notice\":\"Add an input to a DApp's input box with its address.\"}},\"notice\":\"This contract allows anyone to inform the off-chain machine of the address of the DApp contract in a trustless and permissionless way.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/relays/DAppAddressRelay.sol\":\"DAppAddressRelay\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n /**\\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n */\\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\\n\\n /**\\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n * transfers.\\n */\\n event TransferBatch(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256[] ids,\\n uint256[] values\\n );\\n\\n /**\\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n * `approved`.\\n */\\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\\n\\n /**\\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n *\\n * If an {URI} event was emitted for `id`, the standard\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n * returned by {IERC1155MetadataURI-uri}.\\n */\\n event URI(string value, uint256 indexed id);\\n\\n /**\\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(address account, uint256 id) external view returns (uint256);\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\\n external\\n view\\n returns (uint256[] memory);\\n\\n /**\\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n *\\n * Emits an {ApprovalForAll} event.\\n *\\n * Requirements:\\n *\\n * - `operator` cannot be the caller.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n *\\n * See {setApprovalForAll}.\\n */\\n function isApprovedForAll(address account, address operator) external view returns (bool);\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes calldata data\\n ) external;\\n}\\n\",\"keccak256\":\"0x6392f2cfe3a5ee802227fe7a2dfd47096d881aec89bddd214b35c5b46d3cd941\",\"license\":\"MIT\"},\"@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.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"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/common/InputEncoding.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC1155} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/// @title Input Encoding Library\\n\\n/// @notice Defines the encoding of inputs added by core trustless and\\n/// permissionless contracts, such as portals and relays.\\nlibrary InputEncoding {\\n /// @notice Encode an Ether deposit.\\n /// @param sender The Ether sender\\n /// @param value The amount of Ether being sent in Wei\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeEtherDeposit(\\n address sender,\\n uint256 value,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n sender, // 20B\\n value, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-20 token deposit.\\n /// @param ret The return value of `transferFrom`\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param amount The amount of tokens being sent\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeERC20Deposit(\\n bool ret,\\n IERC20 token,\\n address sender,\\n uint256 amount,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n ret, // 1B\\n token, // 20B\\n sender, // 20B\\n amount, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-721 token deposit.\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param tokenId The token identifier\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeERC721Deposit(\\n IERC721 token,\\n address sender,\\n uint256 tokenId,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 single token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenId The identifier of the token being transferred\\n /// @param value Transfer amount\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeSingleERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256 tokenId,\\n uint256 value,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n value, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 batch token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenIds The identifiers of the tokens being transferred\\n /// @param values Transfer amounts per token type\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeBatchERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256[] calldata tokenIds,\\n uint256[] calldata values,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(\\n tokenIds,\\n values,\\n baseLayerData,\\n execLayerData\\n );\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode a DApp address relay.\\n /// @param dapp The DApp address\\n /// @return The encoded input\\n function encodeDAppAddressRelay(\\n address dapp\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n dapp // 20B\\n );\\n }\\n}\\n\",\"keccak256\":\"0x5c60933c8ac9f98004fde0748aee3561effb471eaa52898773dedf6fc5b7eb9e\",\"license\":\"Apache-2.0\"},\"contracts/inputs/IInputBox.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Input Box interface\\ninterface IInputBox {\\n /// @notice Emitted when an input is added to a DApp's input box.\\n /// @param dapp The address of the DApp\\n /// @param inboxInputIndex The index of the input in the input box\\n /// @param sender The address that sent the input\\n /// @param input The contents of the input\\n /// @dev MUST be triggered on a successful call to `addInput`.\\n event InputAdded(\\n address indexed dapp,\\n uint256 indexed inboxInputIndex,\\n address sender,\\n bytes input\\n );\\n\\n /// @notice Add an input to a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _input The contents of the input\\n /// @return The hash of the input plus some extra metadata\\n /// @dev MUST fire an `InputAdded` event accordingly.\\n function addInput(\\n address _dapp,\\n bytes calldata _input\\n ) external returns (bytes32);\\n\\n /// @notice Get the number of inputs in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @return Number of inputs in the DApp's input box\\n function getNumberOfInputs(address _dapp) external view returns (uint256);\\n\\n /// @notice Get the hash of an input in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _index The index of the input in the DApp's input box\\n /// @return The hash of the input at the provided index in the DApp's input box\\n /// @dev `_index` MUST be in the interval `[0,n)` where `n` is the number of\\n /// inputs in the DApp's input box. See the `getNumberOfInputs` function.\\n function getInputHash(\\n address _dapp,\\n uint256 _index\\n ) external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x2addd467a24cde2131784103080aeb28df40d87ba19c5fd92bf96c0c074603df\",\"license\":\"Apache-2.0\"},\"contracts/relays/DAppAddressRelay.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IDAppAddressRelay} from \\\"./IDAppAddressRelay.sol\\\";\\nimport {Relay} from \\\"./Relay.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\nimport {InputEncoding} from \\\"../common/InputEncoding.sol\\\";\\n\\n/// @title DApp Address Relay\\n///\\n/// @notice This contract allows anyone to inform the off-chain machine\\n/// of the address of the DApp contract in a trustless and permissionless way.\\ncontract DAppAddressRelay is Relay, IDAppAddressRelay {\\n /// @notice Constructs the relay.\\n /// @param _inputBox The input box used by the relay\\n constructor(IInputBox _inputBox) Relay(_inputBox) {}\\n\\n function relayDAppAddress(address _dapp) external override {\\n bytes memory input = InputEncoding.encodeDAppAddressRelay(_dapp);\\n inputBox.addInput(_dapp, input);\\n }\\n}\\n\",\"keccak256\":\"0x0841b858717f71558000d40d0f9783e980502ee7083b5750bee0098c3db7914c\",\"license\":\"Apache-2.0\"},\"contracts/relays/IDAppAddressRelay.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IRelay} from \\\"./IRelay.sol\\\";\\n\\n/// @title DApp Address Relay interface\\ninterface IDAppAddressRelay is IRelay {\\n // Permissionless functions\\n\\n /// @notice Add an input to a DApp's input box with its address.\\n /// @param _dapp The address of the DApp\\n function relayDAppAddress(address _dapp) external;\\n}\\n\",\"keccak256\":\"0xc41aa385211232d604230e20de59afd3395dc1518e0b6456083c8bec0ad15fec\",\"license\":\"Apache-2.0\"},\"contracts/relays/IRelay.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Relay interface\\ninterface IRelay {\\n // Permissionless functions\\n\\n /// @notice Get the input box used by this relay.\\n /// @return The input box\\n function getInputBox() external view returns (IInputBox);\\n}\\n\",\"keccak256\":\"0x4475a7cd27333c6cc477d232d08e5cc5f7469b4c0f16716b042dd69e654e2630\",\"license\":\"Apache-2.0\"},\"contracts/relays/Relay.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IRelay} from \\\"./IRelay.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Relay\\n/// @notice This contract serves as a base for all the other relays.\\ncontract Relay is IRelay {\\n /// @notice The input box used by the relay.\\n IInputBox internal immutable inputBox;\\n\\n /// @notice Constructs the relay.\\n /// @param _inputBox The input box used by the relay\\n constructor(IInputBox _inputBox) {\\n inputBox = _inputBox;\\n }\\n\\n function getInputBox() external view override returns (IInputBox) {\\n return inputBox;\\n }\\n}\\n\",\"keccak256\":\"0xeb51ca4468d6dc9cbdc1480e7770e7113d12fe9bd312ef9ea140273fa5af4f0a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b506040516102bc3803806102bc83398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b60805161022c61009060003960008181603c015260c8015261022c6000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062aace9a1461003a5780633016f49e14610077575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a61008536600461014f565b61008c565b005b60408051606083901b6bffffffffffffffffffffffff19166020820152815180820360140181526034820192839052631789cd6360e01b9092527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631789cd6390610107908590859060380161017f565b6020604051808303816000875af1158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906101dd565b505050565b60006020828403121561016157600080fd5b81356001600160a01b038116811461017857600080fd5b9392505050565b60018060a01b038316815260006020604081840152835180604085015260005b818110156101bb5785810183015185820160600152820161019f565b506000606082860101526060601f19601f830116850101925050509392505050565b6000602082840312156101ef57600080fd5b505191905056fea2646970667358221220116a276422bbafa94b50fec58f993e99de2767671d4a5ca3b41746daf04850b064736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062aace9a1461003a5780633016f49e14610077575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a61008536600461014f565b61008c565b005b60408051606083901b6bffffffffffffffffffffffff19166020820152815180820360140181526034820192839052631789cd6360e01b9092527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631789cd6390610107908590859060380161017f565b6020604051808303816000875af1158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906101dd565b505050565b60006020828403121561016157600080fd5b81356001600160a01b038116811461017857600080fd5b9392505050565b60018060a01b038316815260006020604081840152835180604085015260005b818110156101bb5785810183015185820160600152820161019f565b506000606082860101526060601f19601f830116850101925050509392505050565b6000602082840312156101ef57600080fd5b505191905056fea2646970667358221220116a276422bbafa94b50fec58f993e99de2767671d4a5ca3b41746daf04850b064736f6c63430008130033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_inputBox": "The input box used by the relay" + } + }, + "getInputBox()": { + "returns": { + "_0": "The input box" + } + }, + "relayDAppAddress(address)": { + "params": { + "_dapp": "The address of the DApp" + } + } + }, + "title": "DApp Address Relay", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Constructs the relay." + }, + "getInputBox()": { + "notice": "Get the input box used by this relay." + }, + "relayDAppAddress(address)": { + "notice": "Add an input to a DApp's input box with its address." + } + }, + "notice": "This contract allows anyone to inform the off-chain machine of the address of the DApp contract in a trustless and permissionless way.", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/localhost/DiamondCutFacet.json b/deployments/localhost/DiamondCutFacet.json deleted file mode 100644 index 95f5cf6..0000000 --- a/deployments/localhost/DiamondCutFacet.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "address": "0x10dc33852b996A4C8A391d6Ed224FD89A3aD1ceE", - "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": "0x200ee5455aba17e7079795b6815b0a84b6a976957ea1d10a647b911ff03a4e94", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "1070442", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x0ef7c4be27b4da010c5845b60df1ed1fbe2fbf5dbc42b34ded82631388fbb807", - "transactionHash": "0x200ee5455aba17e7079795b6815b0a84b6a976957ea1d10a647b911ff03a4e94", - "logs": [], - "blockNumber": 16, - "cumulativeGasUsed": "1070442", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\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\":\"0x581eb846bee3d62731f4fc5bf21aa9cf744f491075941de685797f107e5d06f2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061125e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e366004610d90565b610045565b005b61004d61027b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e547fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c9061ffff8116908190600090600716156100bc5750600381901c60009081526001840160205260409020545b60005b888110156101b35761019c83838c8c858181106100de576100de610e42565b90506020028101906100f09190610e58565b6100fe906020810190610e78565b8d8d8681811061011057610110610e42565b90506020028101906101229190610e58565b610133906040810190602001610ea9565b8e8e8781811061014557610145610e42565b90506020028101906101579190610e58565b610165906040810190610ec4565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061030992505050565b9093509150806101ab81610f24565b9150506100bf565b508282146101cf5760028401805461ffff191661ffff84161790555b60078216156101f157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738989898989604051610228959493929190610fcc565b60405180910390a16102708787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610af792505050565b505050505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b031633146103075760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b565b600080807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c905060008451116103955760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084016102fe565b60008560028111156103a9576103a9610f3d565b03610516576103d0866040518060600160405280602481526020016111b560249139610d0a565b60005b84518110156105105760008582815181106103f0576103f0610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104895760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b60648201526084016102fe565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104ed5760038c901c600090815260018601602052604081209b909b555b8b6104f781610f24565b9c5050505050808061050890610f24565b9150506103d3565b50610aeb565b600185600281111561052a5761052a610f3d565b03610759576105518660405180606001604052806028815260200161120160289139610d0a565b60005b845181101561051057600085828151811061057157610571610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c3081036106065760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b60648201526084016102fe565b896001600160a01b0316816001600160a01b03160361068d5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016102fe565b6001600160a01b0381166107095760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016102fe565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b161790558061075181610f24565b915050610554565b600285600281111561076d5761076d610f3d565b03610a93576001600160a01b038616156107e85760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b60648201526084016102fe565b600388901c6007891660005b8651811015610a735760008a90036108305782610810816110f5565b60008181526001870160205260409020549b5093506007925061083e9050565b8161083a816110f5565b9250505b6000806000808a858151811061085657610856610e42565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6108f65760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016102fe565b30606082901c036109605760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b60648201526084016102fe565b600587901b8f901b94506001600160e01b0319808616908316146109b6576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214610a1b576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c179055610a3f565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b84600003610a5d57600086815260018801602052604081208190559c505b5050508080610a6b90610f24565b9150506107f4565b5080610a8083600861110c565b610a8a919061112b565b99505050610aeb565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084016102fe565b50959694955050505050565b6001600160a01b038216610b7e57805115610b7a5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d7074790000000060648201526084016102fe565b5050565b6000815111610bf55760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f74206164647265737328302900000060648201526084016102fe565b6001600160a01b0382163014610c2757610c27826040518060600160405280602881526020016111d960289139610d0a565b600080836001600160a01b031683604051610c42919061116f565b600060405180830381855af49150503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b509150915081610d0457805115610cad578060405162461bcd60e51b81526004016102fe9190611181565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b60648201526084016102fe565b50505050565b813b8181610d045760405162461bcd60e51b81526004016102fe9190611181565b80356001600160a01b0381168114610d4257600080fd5b919050565b60008083601f840112610d5957600080fd5b50813567ffffffffffffffff811115610d7157600080fd5b602083019150836020828501011115610d8957600080fd5b9250929050565b600080600080600060608688031215610da857600080fd5b853567ffffffffffffffff80821115610dc057600080fd5b818801915088601f830112610dd457600080fd5b813581811115610de357600080fd5b8960208260051b8501011115610df857600080fd5b60208301975080965050610e0e60208901610d2b565b94506040880135915080821115610e2457600080fd5b50610e3188828901610d47565b969995985093965092949392505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112610e6e57600080fd5b9190910192915050565b600060208284031215610e8a57600080fd5b610e9382610d2b565b9392505050565b803560038110610d4257600080fd5b600060208284031215610ebb57600080fd5b610e9382610e9a565b6000808335601e19843603018112610edb57600080fd5b83018035915067ffffffffffffffff821115610ef657600080fd5b6020019150600581901b3603821315610d8957600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610f3657610f36610f0e565b5060010190565b634e487b7160e01b600052602160045260246000fd5b818352600060208085019450826000805b86811015610f975782356001600160e01b03198116808214610f84578384fd5b8952509683019691830191600101610f64565b50959695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060808252818101869052600090600560808085019089831b8601018a855b8b8110156110c257878303607f190184528135368e9003605e1901811261101157600080fd5b8d016001600160a01b0361102482610d2b565b1684526020611034818301610e9a565b6003811061105257634e487b7160e01b600052602160045260246000fd5b8582015260408281013536849003601e1901811261106f57600080fd5b8301803567ffffffffffffffff81111561108857600080fd5b808a1b360385131561109957600080fd5b8a838901526110ad8b890182868501610f53565b98840198975050509301925050600101610feb565b50506001600160a01b038916602087015285810360408701526110e681888a610fa3565b9b9a5050505050505050505050565b60008161110457611104610f0e565b506000190190565b600081600019048311821515161561112657611126610f0e565b500290565b6000821982111561113e5761113e610f0e565b500190565b60005b8381101561115e578181015183820152602001611146565b83811115610d045750506000910152565b60008251610e6e818460208701611143565b60208152600082518060208401526111a0816040850160208701611143565b601f01601f1916919091016040019291505056fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a264697066735822122028861677406609588a7a33a9c38e767246f8fdbbbb783c2eb6d3bd23f64a309664736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e366004610d90565b610045565b005b61004d61027b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e547fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c9061ffff8116908190600090600716156100bc5750600381901c60009081526001840160205260409020545b60005b888110156101b35761019c83838c8c858181106100de576100de610e42565b90506020028101906100f09190610e58565b6100fe906020810190610e78565b8d8d8681811061011057610110610e42565b90506020028101906101229190610e58565b610133906040810190602001610ea9565b8e8e8781811061014557610145610e42565b90506020028101906101579190610e58565b610165906040810190610ec4565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061030992505050565b9093509150806101ab81610f24565b9150506100bf565b508282146101cf5760028401805461ffff191661ffff84161790555b60078216156101f157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738989898989604051610228959493929190610fcc565b60405180910390a16102708787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610af792505050565b505050505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b031633146103075760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b565b600080807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c905060008451116103955760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b60648201526084016102fe565b60008560028111156103a9576103a9610f3d565b03610516576103d0866040518060600160405280602481526020016111b560249139610d0a565b60005b84518110156105105760008582815181106103f0576103f0610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c156104895760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b60648201526084016102fe565b6001600160e01b031980831660008181526020879052604090206001600160601b031960608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036104ed5760038c901c600090815260018601602052604081209b909b555b8b6104f781610f24565b9c5050505050808061050890610f24565b9150506103d3565b50610aeb565b600185600281111561052a5761052a610f3d565b03610759576105518660405180606001604052806028815260200161120160289139610d0a565b60005b845181101561051057600085828151811061057157610571610e42565b6020908102919091018101516001600160e01b03198116600090815291859052604090912054909150606081901c3081036106065760405162461bcd60e51b815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201526e3aba30b1363290333ab731ba34b7b760891b60648201526084016102fe565b896001600160a01b0316816001600160a01b03160361068d5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016102fe565b6001600160a01b0381166107095760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016102fe565b506001600160e01b031990911660009081526020849052604090206bffffffffffffffffffffffff919091166001600160601b031960608a901b161790558061075181610f24565b915050610554565b600285600281111561076d5761076d610f3d565b03610a93576001600160a01b038616156107e85760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b60648201526084016102fe565b600388901c6007891660005b8651811015610a735760008a90036108305782610810816110f5565b60008181526001870160205260409020549b5093506007925061083e9050565b8161083a816110f5565b9250505b6000806000808a858151811061085657610856610e42565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c6108f65760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016102fe565b30606082901c036109605760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b60648201526084016102fe565b600587901b8f901b94506001600160e01b0319808616908316146109b6576001600160e01b03198516600090815260208a90526040902080546001600160601b0319166bffffffffffffffffffffffff83161790555b6001600160e01b031991909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214610a1b576000828152600188016020526040902080546001600160e01b031980841c19909116908516831c179055610a3f565b80836001600160e01b031916901c816001600160e01b031960001b901c198e16179c505b84600003610a5d57600086815260018801602052604081208190559c505b5050508080610a6b90610f24565b9150506107f4565b5080610a8083600861110c565b610a8a919061112b565b99505050610aeb565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084016102fe565b50959694955050505050565b6001600160a01b038216610b7e57805115610b7a5760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d7074790000000060648201526084016102fe565b5050565b6000815111610bf55760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f74206164647265737328302900000060648201526084016102fe565b6001600160a01b0382163014610c2757610c27826040518060600160405280602881526020016111d960289139610d0a565b600080836001600160a01b031683604051610c42919061116f565b600060405180830381855af49150503d8060008114610c7d576040519150601f19603f3d011682016040523d82523d6000602084013e610c82565b606091505b509150915081610d0457805115610cad578060405162461bcd60e51b81526004016102fe9190611181565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b60648201526084016102fe565b50505050565b813b8181610d045760405162461bcd60e51b81526004016102fe9190611181565b80356001600160a01b0381168114610d4257600080fd5b919050565b60008083601f840112610d5957600080fd5b50813567ffffffffffffffff811115610d7157600080fd5b602083019150836020828501011115610d8957600080fd5b9250929050565b600080600080600060608688031215610da857600080fd5b853567ffffffffffffffff80821115610dc057600080fd5b818801915088601f830112610dd457600080fd5b813581811115610de357600080fd5b8960208260051b8501011115610df857600080fd5b60208301975080965050610e0e60208901610d2b565b94506040880135915080821115610e2457600080fd5b50610e3188828901610d47565b969995985093965092949392505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112610e6e57600080fd5b9190910192915050565b600060208284031215610e8a57600080fd5b610e9382610d2b565b9392505050565b803560038110610d4257600080fd5b600060208284031215610ebb57600080fd5b610e9382610e9a565b6000808335601e19843603018112610edb57600080fd5b83018035915067ffffffffffffffff821115610ef657600080fd5b6020019150600581901b3603821315610d8957600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610f3657610f36610f0e565b5060010190565b634e487b7160e01b600052602160045260246000fd5b818352600060208085019450826000805b86811015610f975782356001600160e01b03198116808214610f84578384fd5b8952509683019691830191600101610f64565b50959695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060808252818101869052600090600560808085019089831b8601018a855b8b8110156110c257878303607f190184528135368e9003605e1901811261101157600080fd5b8d016001600160a01b0361102482610d2b565b1684526020611034818301610e9a565b6003811061105257634e487b7160e01b600052602160045260246000fd5b8582015260408281013536849003601e1901811261106f57600080fd5b8301803567ffffffffffffffff81111561108857600080fd5b808a1b360385131561109957600080fd5b8a838901526110ad8b890182868501610f53565b98840198975050509301925050600101610feb565b50506001600160a01b038916602087015285810360408701526110e681888a610fa3565b9b9a5050505050505050505050565b60008161110457611104610f0e565b506000190190565b600081600019048311821515161561112657611126610f0e565b500290565b6000821982111561113e5761113e610f0e565b500190565b60005b8381101561115e578181015183820152602001611146565b83811115610d045750506000910152565b60008251610e6e818460208701611143565b60208152600082518060208401526111a0816040850160208701611143565b601f01601f1916919091016040019291505056fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a264697066735822122028861677406609588a7a33a9c38e767246f8fdbbbb783c2eb6d3bd23f64a309664736f6c634300080d0033", - "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/deployments/localhost/DiamondInit.json b/deployments/localhost/DiamondInit.json deleted file mode 100644 index fe915d8..0000000 --- a/deployments/localhost/DiamondInit.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "address": "0xCbEDAB3193dc8027cc403a01cE054695a08E2F34", - "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": "0x7544ac043a36855354bb51a84dab77085a24f43b32318954fb319286e33ed57d", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "645412", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf839df7888446592f1cf33489ad66bbdf66a6521ab8b4578aad44f969e3e4ac7", - "transactionHash": "0x7544ac043a36855354bb51a84dab77085a24f43b32318954fb319286e33ed57d", - "logs": [], - "blockNumber": 27, - "cumulativeGasUsed": "645412", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n address _facet\\n ) external view 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(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xdc5991b0218ab6b2cd78983c19f74a789a79ec9a9ba756ae05c8dcd512c13e38\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\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\":\"0x581eb846bee3d62731f4fc5bf21aa9cf744f491075941de685797f107e5d06f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"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(\\n address payable[] memory _validators\\n ) private {\\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\":\"0xab936fa5e183f87bb4421ea393b10d37eaf0ab648ad6f0d8d6be49d545a0b644\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610ab1806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063af52770114610030575b600080fd5b61004361003e3660046108d6565b610045565b005b6101267fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f6020527f699d9daa71b280d05a152715774afa0a81a312594b2d731d6b0b2552b7d6f69f8054600160ff1991821681179092557ff97e938d8af42f52387bb74b8b526fda8f184cc2aa534340a8d75a88fbecc77580548216831790557f65d510a5d8f7ef134ec444f7f34ee808c8eeb5177cdfd16be0c40fe1ab43369580548216831790556307f5828d60e41b6000527f5622121b47b8cd0120c4efe45dd5483242f54a3d49bd7679be565d47694918c380549091169091179055565b61016d61013660e0830183610912565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506101be92505050565b610181813560208301356040840135610260565b6101ae608082013561019960c0840160a08501610963565b6101a960e0850160c08601610963565b610339565b6101bb8160600135610407565b50565b80517f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc90600881111561022d5760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b60448201526064015b60405180910390fd5b8251610242906001840190602086019061085c565b5060028201819055610253816104ae565b8260030181905550505050565b7fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c8381557fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189d805463ffffffff8481166401000000000267ffffffffffffffff19909216868216179190911773ffffffff00000000ffffffff0000000000000000191642909116600160401b0263ffffffff60801b191617905560408051848152602081018490527fd6f5a5cd17f05cf9045751ee10f662f62e569c9371ffec8380510aabe63012d391015b60405180910390a150505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc748390557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7580546001600160a01b038481166001600160a01b031992831681179093557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7380549185169190921681178255604080518781526020810194909452830152907f5b54873359173c3d639e39928ad34e113039ce7c799d500e57f8a2c703adb4779060600161032b565b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6003821080159061043a575060408211155b6104865760405162461bcd60e51b815260206004820152601960248201527f4c6f67206f6620696e7075742073697a653a205b332c36345d000000000000006044820152606401610224565b6001821b60028201556040805160208101909152600081526104a990829061050f565b505050565b600060088211156104f65760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b6044820152606401610224565b6000610505600180851b6109b8565b60f01b9392505050565b600061051c838330610523565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561059d5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610224565b6105a6816106c8565b156105b4576105b48561079b565b600085600301546000146105cb57856001016105cd565b855b905060006105da836107ba565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161067f91906109b8565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516106b3939291906109cf565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156106f0576106f061098c565b600184015490915063ffffffff600160401b820481169116600083600281111561071c5761071c61098c565b148015610731575061072e8183610a3b565b42115b15610790576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161077d91610a53565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156107ac5760006107af565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156108265761082661098c565b9050600081600281111561083c5761083c61098c565b146108515761084c826001610a3b565b610853565b815b95945050505050565b8280548282559060005260206000209081019282156108b1579160200282015b828111156108b157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061087c565b506108bd9291506108c1565b5090565b5b808211156108bd57600081556001016108c2565b6000602082840312156108e857600080fd5b813567ffffffffffffffff8111156108ff57600080fd5b8201610100818503121561051c57600080fd5b6000808335601e1984360301811261092957600080fd5b83018035915067ffffffffffffffff82111561094457600080fd5b6020019150600581901b360382131561095c57600080fd5b9250929050565b60006020828403121561097557600080fd5b81356001600160a01b038116811461051c57600080fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156109ca576109ca6109a2565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610a11578581018301518582016080015282016109f5565b81811115610a23576000608083870101525b50601f01601f19169290920160800195945050505050565b60008219821115610a4e57610a4e6109a2565b500190565b6020810160038310610a7557634e487b7160e01b600052602160045260246000fd5b9190529056fea2646970667358221220ae9d04c8637c04ddcc005a0a84b4f6ff2b5c6c3077ebb1fe7cc418b79d79d4ef64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063af52770114610030575b600080fd5b61004361003e3660046108d6565b610045565b005b6101267fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f6020527f699d9daa71b280d05a152715774afa0a81a312594b2d731d6b0b2552b7d6f69f8054600160ff1991821681179092557ff97e938d8af42f52387bb74b8b526fda8f184cc2aa534340a8d75a88fbecc77580548216831790557f65d510a5d8f7ef134ec444f7f34ee808c8eeb5177cdfd16be0c40fe1ab43369580548216831790556307f5828d60e41b6000527f5622121b47b8cd0120c4efe45dd5483242f54a3d49bd7679be565d47694918c380549091169091179055565b61016d61013660e0830183610912565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506101be92505050565b610181813560208301356040840135610260565b6101ae608082013561019960c0840160a08501610963565b6101a960e0850160c08601610963565b610339565b6101bb8160600135610407565b50565b80517f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc90600881111561022d5760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b60448201526064015b60405180910390fd5b8251610242906001840190602086019061085c565b5060028201819055610253816104ae565b8260030181905550505050565b7fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c8381557fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189d805463ffffffff8481166401000000000267ffffffffffffffff19909216868216179190911773ffffffff00000000ffffffff0000000000000000191642909116600160401b0263ffffffff60801b191617905560408051848152602081018490527fd6f5a5cd17f05cf9045751ee10f662f62e569c9371ffec8380510aabe63012d391015b60405180910390a150505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc748390557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7580546001600160a01b038481166001600160a01b031992831681179093557f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7380549185169190921681178255604080518781526020810194909452830152907f5b54873359173c3d639e39928ad34e113039ce7c799d500e57f8a2c703adb4779060600161032b565b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6003821080159061043a575060408211155b6104865760405162461bcd60e51b815260206004820152601960248201527f4c6f67206f6620696e7075742073697a653a205b332c36345d000000000000006044820152606401610224565b6001821b60028201556040805160208101909152600081526104a990829061050f565b505050565b600060088211156104f65760405162461bcd60e51b8152602060048201526012602482015271757020746f20382076616c696461746f727360701b6044820152606401610224565b6000610505600180851b6109b8565b60f01b9392505050565b600061051c838330610523565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561059d5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610224565b6105a6816106c8565b156105b4576105b48561079b565b600085600301546000146105cb57856001016105cd565b855b905060006105da836107ba565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161067f91906109b8565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516106b3939291906109cf565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156106f0576106f061098c565b600184015490915063ffffffff600160401b820481169116600083600281111561071c5761071c61098c565b148015610731575061072e8183610a3b565b42115b15610790576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161077d91610a53565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156107ac5760006107af565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156108265761082661098c565b9050600081600281111561083c5761083c61098c565b146108515761084c826001610a3b565b610853565b815b95945050505050565b8280548282559060005260206000209081019282156108b1579160200282015b828111156108b157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061087c565b506108bd9291506108c1565b5090565b5b808211156108bd57600081556001016108c2565b6000602082840312156108e857600080fd5b813567ffffffffffffffff8111156108ff57600080fd5b8201610100818503121561051c57600080fd5b6000808335601e1984360301811261092957600080fd5b83018035915067ffffffffffffffff82111561094457600080fd5b6020019150600581901b360382131561095c57600080fd5b9250929050565b60006020828403121561097557600080fd5b81356001600160a01b038116811461051c57600080fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156109ca576109ca6109a2565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610a11578581018301518582016080015282016109f5565b81811115610a23576000608083870101525b50601f01601f19169290920160800195945050505050565b60008219821115610a4e57610a4e6109a2565b500190565b6020810160038310610a7557634e487b7160e01b600052602160045260246000fd5b9190529056fea2646970667358221220ae9d04c8637c04ddcc005a0a84b4f6ff2b5c6c3077ebb1fe7cc418b79d79d4ef64736f6c634300080d0033", - "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/deployments/localhost/DiamondLoupeFacet.json b/deployments/localhost/DiamondLoupeFacet.json deleted file mode 100644 index 0ff3cc9..0000000 --- a/deployments/localhost/DiamondLoupeFacet.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "address": "0x8339b06c37d488d51aB838f6C758D61ddb1F1C6c", - "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": "0x83ff50b33df2bd51142ada59ae0de5969bc8e828f558e993934372ac0c525f0b", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "670579", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x65a7a6abf9869cda2fc967ccecf115b57500157259ac44ce2b4ad7abfc981cb0", - "transactionHash": "0x83ff50b33df2bd51142ada59ae0de5969bc8e828f558e993934372ac0c525f0b", - "logs": [], - "blockNumber": 17, - "cumulativeGasUsed": "670579", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\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(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n }\\n\\n // This implements ERC-165.\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n return ds.supportedInterfaces[_interfaceId];\\n }\\n}\\n\",\"keccak256\":\"0x1b525af17a3f7f703dd7ac2606b6b266e1b2bfa90901c34991cb0fecdd0b28b5\",\"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(\\n address _facet\\n ) external view 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(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xdc5991b0218ab6b2cd78983c19f74a789a79ec9a9ba756ae05c8dcd512c13e38\",\"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(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\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\":\"0x581eb846bee3d62731f4fc5bf21aa9cf744f491075941de685797f107e5d06f2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610b24806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806301ffc9a71461005c57806352ef6b2c146100bd5780637a0ed627146100d2578063adfca15e146100e7578063cdffacc614610107575b600080fd5b6100a861006a3660046108d8565b6001600160e01b03191660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f602052604090205460ff1690565b60405190151581526020015b60405180910390f35b6100c5610159565b6040516100b49190610909565b6100da61031d565b6040516100b4919061099b565b6100fa6100f5366004610a18565b610766565b6040516100b49190610a41565b6101416101153660046108d8565b6001600160e01b0319166000908152600080516020610acf833981519152602052604090205460601c90565b6040516001600160a01b0390911681526020016100b4565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff8111156101aa576101aa610a54565b6040519080825280602002602001820160405280156101d3578160200160208202803683370190505b50915060008060005b600284015461ffff16821015610315576000818152600185016020526040812054905b6008811015610300578361021281610a80565b600288015490955061ffff168511905061030057600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156102a3578a818151811061026857610268610a99565b60200260200101516001600160a01b0316836001600160a01b03160361029157600191506102a3565b8061029b81610a80565b91505061024e565b5080156102b2575050506102ee565b818a89815181106102c5576102c5610a99565b6001600160a01b0390921660209283029190910190910152876102e781610a80565b9850505050505b806102f881610a80565b9150506101ff565b5050808061030d90610a80565b9150506101dc565b505082525090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff81111561036e5761036e610a54565b6040519080825280602002602001820160405280156103b457816020015b60408051808201909152600081526060602082015281526020019060019003908161038c5790505b50600282015490925060009061ffff1667ffffffffffffffff8111156103dc576103dc610a54565b604051908082528060200260200182016040528015610405578160200160208202803683370190505b50905060008060005b600285015461ffff168210156106f4576000818152600186016020526040812054905b60088110156106df578361044481610a80565b600289015490955061ffff16851190506106df57600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b8881101561059d57826001600160a01b03168c82815181106104a4576104a4610a99565b6020026020010151600001516001600160a01b03160361058b57838c82815181106104d1576104d1610a99565b6020026020010151602001518b83815181106104ef576104ef610a99565b602002602001015160ff168151811061050a5761050a610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061054057610540610a99565b602002602001015160ff161061055557600080fd5b89818151811061056757610567610a99565b60200260200101805180919061057c90610aaf565b60ff169052506001915061059d565b8061059581610a80565b915050610480565b5080156105ac575050506106cd565b818b89815181106105bf576105bf610a99565b60209081029190910101516001600160a01b03909116905260028a015461ffff1667ffffffffffffffff8111156105f8576105f8610a54565b604051908082528060200260200182016040528015610621578160200160208202803683370190505b508b898151811061063457610634610a99565b602002602001015160200181905250828b898151811061065657610656610a99565b60200260200101516020015160008151811061067457610674610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106106aa576106aa610a99565b60ff90921660209283029190910190910152876106c681610a80565b9850505050505b806106d781610a80565b915050610431565b505080806106ec90610a80565b91505061040e565b5060005b8281101561075b57600084828151811061071457610714610a99565b602002602001015160ff169050600087838151811061073557610735610a99565b60200260200101516020015190508181525050808061075390610a80565b9150506106f8565b508185525050505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529060009061ffff1667ffffffffffffffff8111156107ba576107ba610a54565b6040519080825280602002602001820160405280156107e3578160200160208202803683370190505b5092506000805b600284015461ffff168210156108ce576000818152600185016020526040812054905b60088110156108b9578361082081610a80565b600288015490955061ffff16851190506108b957600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a168190036108a4578189888151811061087d5761087d610a99565b6001600160e01b031990921660209283029190910190910152866108a081610a80565b9750505b505080806108b190610a80565b91505061080d565b505080806108c690610a80565b9150506107ea565b5050825250919050565b6000602082840312156108ea57600080fd5b81356001600160e01b03198116811461090257600080fd5b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561094a5783516001600160a01b031683529284019291840191600101610925565b50909695505050505050565b600081518084526020808501945080840160005b838110156109905781516001600160e01b0319168752958201959082019060010161096a565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015610a0a57888303603f19018552815180516001600160a01b031684528701518784018790526109f787850182610956565b95880195935050908601906001016109c2565b509098975050505050505050565b600060208284031215610a2a57600080fd5b81356001600160a01b038116811461090257600080fd5b6020815260006109026020830184610956565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610a9257610a92610a6a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103610ac557610ac5610a6a565b6001019291505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131ca26469706673582212204e806037195fb66d5709c3be05fd9bd079f742dcc7fb62d9b6976c66d764ebf964736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806301ffc9a71461005c57806352ef6b2c146100bd5780637a0ed627146100d2578063adfca15e146100e7578063cdffacc614610107575b600080fd5b6100a861006a3660046108d8565b6001600160e01b03191660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f602052604090205460ff1690565b60405190151581526020015b60405180910390f35b6100c5610159565b6040516100b49190610909565b6100da61031d565b6040516100b4919061099b565b6100fa6100f5366004610a18565b610766565b6040516100b49190610a41565b6101416101153660046108d8565b6001600160e01b0319166000908152600080516020610acf833981519152602052604090205460601c90565b6040516001600160a01b0390911681526020016100b4565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff8111156101aa576101aa610a54565b6040519080825280602002602001820160405280156101d3578160200160208202803683370190505b50915060008060005b600284015461ffff16821015610315576000818152600185016020526040812054905b6008811015610300578361021281610a80565b600288015490955061ffff168511905061030057600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156102a3578a818151811061026857610268610a99565b60200260200101516001600160a01b0316836001600160a01b03160361029157600191506102a3565b8061029b81610a80565b91505061024e565b5080156102b2575050506102ee565b818a89815181106102c5576102c5610a99565b6001600160a01b0390921660209283029190910190910152876102e781610a80565b9850505050505b806102f881610a80565b9150506101ff565b5050808061030d90610a80565b9150506101dc565b505082525090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529061ffff1667ffffffffffffffff81111561036e5761036e610a54565b6040519080825280602002602001820160405280156103b457816020015b60408051808201909152600081526060602082015281526020019060019003908161038c5790505b50600282015490925060009061ffff1667ffffffffffffffff8111156103dc576103dc610a54565b604051908082528060200260200182016040528015610405578160200160208202803683370190505b50905060008060005b600285015461ffff168210156106f4576000818152600186016020526040812054905b60088110156106df578361044481610a80565b600289015490955061ffff16851190506106df57600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b8881101561059d57826001600160a01b03168c82815181106104a4576104a4610a99565b6020026020010151600001516001600160a01b03160361058b57838c82815181106104d1576104d1610a99565b6020026020010151602001518b83815181106104ef576104ef610a99565b602002602001015160ff168151811061050a5761050a610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061054057610540610a99565b602002602001015160ff161061055557600080fd5b89818151811061056757610567610a99565b60200260200101805180919061057c90610aaf565b60ff169052506001915061059d565b8061059581610a80565b915050610480565b5080156105ac575050506106cd565b818b89815181106105bf576105bf610a99565b60209081029190910101516001600160a01b03909116905260028a015461ffff1667ffffffffffffffff8111156105f8576105f8610a54565b604051908082528060200260200182016040528015610621578160200160208202803683370190505b508b898151811061063457610634610a99565b602002602001015160200181905250828b898151811061065657610656610a99565b60200260200101516020015160008151811061067457610674610a99565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106106aa576106aa610a99565b60ff90921660209283029190910190910152876106c681610a80565b9850505050505b806106d781610a80565b915050610431565b505080806106ec90610a80565b91505061040e565b5060005b8281101561075b57600084828151811061071457610714610a99565b602002602001015160ff169050600087838151811061073557610735610a99565b60200260200101516020015190508181525050808061075390610a80565b9150506106f8565b508185525050505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e54606090600080516020610acf8339815191529060009061ffff1667ffffffffffffffff8111156107ba576107ba610a54565b6040519080825280602002602001820160405280156107e3578160200160208202803683370190505b5092506000805b600284015461ffff168210156108ce576000818152600185016020526040812054905b60088110156108b9578361082081610a80565b600288015490955061ffff16851190506108b957600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a168190036108a4578189888151811061087d5761087d610a99565b6001600160e01b031990921660209283029190910190910152866108a081610a80565b9750505b505080806108b190610a80565b91505061080d565b505080806108c690610a80565b9150506107ea565b5050825250919050565b6000602082840312156108ea57600080fd5b81356001600160e01b03198116811461090257600080fd5b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561094a5783516001600160a01b031683529284019291840191600101610925565b50909695505050505050565b600081518084526020808501945080840160005b838110156109905781516001600160e01b0319168752958201959082019060010161096a565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015610a0a57888303603f19018552815180516001600160a01b031684528701518784018790526109f787850182610956565b95880195935050908601906001016109c2565b509098975050505050505050565b600060208284031215610a2a57600080fd5b81356001600160a01b038116811461090257600080fd5b6020815260006109026020830184610956565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610a9257610a92610a6a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103610ac557610ac5610a6a565b6001019291505056fec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131ca26469706673582212204e806037195fb66d5709c3be05fd9bd079f742dcc7fb62d9b6976c66d764ebf964736f6c634300080d0033", - "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/deployments/localhost/ERC20Portal.json b/deployments/localhost/ERC20Portal.json new file mode 100644 index 0000000..e5dcf60 --- /dev/null +++ b/deployments/localhost/ERC20Portal.json @@ -0,0 +1,126 @@ +{ + "address": "0x4340ac4FcdFC5eF8d34930C96BBac2Af1301DF40", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IInputBox", + "name": "_inputBox", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_dapp", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_execLayerData", + "type": "bytes" + } + ], + "name": "depositERC20Tokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getInputBox", + "outputs": [ + { + "internalType": "contract IInputBox", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xfae7a50daeb9ab621b560db196ab5461113f80b4b309b9c5e558ca7c4d3ca1c0", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "265834", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4f208ad1345b113765ef823cd4196ff7158d6706b4beccff2c54c41b5bfbfac7", + "transactionHash": "0xfae7a50daeb9ab621b560db196ab5461113f80b4b309b9c5e558ca7c4d3ca1c0", + "logs": [], + "blockNumber": 15, + "cumulativeGasUsed": "265834", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5a723220579C0DCb8C9253E6b4c62e572E379945" + ], + "numDeployments": 1, + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"_inputBox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_execLayerData\",\"type\":\"bytes\"}],\"name\":\"depositERC20Tokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputBox\",\"outputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_inputBox\":\"The input box used by the portal\"}},\"depositERC20Tokens(address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"The amount of tokens to be transferred\",\"_dapp\":\"The address of the DApp\",\"_execLayerData\":\"Additional data to be interpreted by the execution layer\",\"_token\":\"The ERC-20 token contract\"}},\"getInputBox()\":{\"returns\":{\"_0\":\"The input box\"}}},\"title\":\"ERC-20 Portal\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructs the portal.\"},\"depositERC20Tokens(address,address,uint256,bytes)\":{\"notice\":\"Transfer ERC-20 tokens to a DApp and add an input to the DApp's input box to signal such operation. The caller must allow the portal to withdraw at least `_amount` tokens from their account beforehand, by calling the `approve` function in the token contract.\"},\"getInputBox()\":{\"notice\":\"Get the input box used by this portal.\"}},\"notice\":\"This contract allows anyone to perform transfers of ERC-20 tokens to a DApp while informing the off-chain machine.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/portals/ERC20Portal.sol\":\"ERC20Portal\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n /**\\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n */\\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\\n\\n /**\\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n * transfers.\\n */\\n event TransferBatch(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256[] ids,\\n uint256[] values\\n );\\n\\n /**\\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n * `approved`.\\n */\\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\\n\\n /**\\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n *\\n * If an {URI} event was emitted for `id`, the standard\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n * returned by {IERC1155MetadataURI-uri}.\\n */\\n event URI(string value, uint256 indexed id);\\n\\n /**\\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(address account, uint256 id) external view returns (uint256);\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\\n external\\n view\\n returns (uint256[] memory);\\n\\n /**\\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n *\\n * Emits an {ApprovalForAll} event.\\n *\\n * Requirements:\\n *\\n * - `operator` cannot be the caller.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n *\\n * See {setApprovalForAll}.\\n */\\n function isApprovedForAll(address account, address operator) external view returns (bool);\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes calldata data\\n ) external;\\n}\\n\",\"keccak256\":\"0x6392f2cfe3a5ee802227fe7a2dfd47096d881aec89bddd214b35c5b46d3cd941\",\"license\":\"MIT\"},\"@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.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"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/common/InputEncoding.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC1155} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/// @title Input Encoding Library\\n\\n/// @notice Defines the encoding of inputs added by core trustless and\\n/// permissionless contracts, such as portals and relays.\\nlibrary InputEncoding {\\n /// @notice Encode an Ether deposit.\\n /// @param sender The Ether sender\\n /// @param value The amount of Ether being sent in Wei\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeEtherDeposit(\\n address sender,\\n uint256 value,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n sender, // 20B\\n value, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-20 token deposit.\\n /// @param ret The return value of `transferFrom`\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param amount The amount of tokens being sent\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeERC20Deposit(\\n bool ret,\\n IERC20 token,\\n address sender,\\n uint256 amount,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n ret, // 1B\\n token, // 20B\\n sender, // 20B\\n amount, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-721 token deposit.\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param tokenId The token identifier\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeERC721Deposit(\\n IERC721 token,\\n address sender,\\n uint256 tokenId,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 single token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenId The identifier of the token being transferred\\n /// @param value Transfer amount\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeSingleERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256 tokenId,\\n uint256 value,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n value, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 batch token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenIds The identifiers of the tokens being transferred\\n /// @param values Transfer amounts per token type\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeBatchERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256[] calldata tokenIds,\\n uint256[] calldata values,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(\\n tokenIds,\\n values,\\n baseLayerData,\\n execLayerData\\n );\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode a DApp address relay.\\n /// @param dapp The DApp address\\n /// @return The encoded input\\n function encodeDAppAddressRelay(\\n address dapp\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n dapp // 20B\\n );\\n }\\n}\\n\",\"keccak256\":\"0x5c60933c8ac9f98004fde0748aee3561effb471eaa52898773dedf6fc5b7eb9e\",\"license\":\"Apache-2.0\"},\"contracts/inputs/IInputBox.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Input Box interface\\ninterface IInputBox {\\n /// @notice Emitted when an input is added to a DApp's input box.\\n /// @param dapp The address of the DApp\\n /// @param inboxInputIndex The index of the input in the input box\\n /// @param sender The address that sent the input\\n /// @param input The contents of the input\\n /// @dev MUST be triggered on a successful call to `addInput`.\\n event InputAdded(\\n address indexed dapp,\\n uint256 indexed inboxInputIndex,\\n address sender,\\n bytes input\\n );\\n\\n /// @notice Add an input to a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _input The contents of the input\\n /// @return The hash of the input plus some extra metadata\\n /// @dev MUST fire an `InputAdded` event accordingly.\\n function addInput(\\n address _dapp,\\n bytes calldata _input\\n ) external returns (bytes32);\\n\\n /// @notice Get the number of inputs in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @return Number of inputs in the DApp's input box\\n function getNumberOfInputs(address _dapp) external view returns (uint256);\\n\\n /// @notice Get the hash of an input in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _index The index of the input in the DApp's input box\\n /// @return The hash of the input at the provided index in the DApp's input box\\n /// @dev `_index` MUST be in the interval `[0,n)` where `n` is the number of\\n /// inputs in the DApp's input box. See the `getNumberOfInputs` function.\\n function getInputHash(\\n address _dapp,\\n uint256 _index\\n ) external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x2addd467a24cde2131784103080aeb28df40d87ba19c5fd92bf96c0c074603df\",\"license\":\"Apache-2.0\"},\"contracts/portals/ERC20Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport {IERC20Portal} from \\\"./IERC20Portal.sol\\\";\\nimport {Portal} from \\\"./Portal.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\nimport {InputEncoding} from \\\"../common/InputEncoding.sol\\\";\\n\\n/// @title ERC-20 Portal\\n///\\n/// @notice This contract allows anyone to perform transfers of\\n/// ERC-20 tokens to a DApp while informing the off-chain machine.\\ncontract ERC20Portal is Portal, IERC20Portal {\\n /// @notice Constructs the portal.\\n /// @param _inputBox The input box used by the portal\\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\\n\\n function depositERC20Tokens(\\n IERC20 _token,\\n address _dapp,\\n uint256 _amount,\\n bytes calldata _execLayerData\\n ) external override {\\n bool success = _token.transferFrom(msg.sender, _dapp, _amount);\\n\\n bytes memory input = InputEncoding.encodeERC20Deposit(\\n success,\\n _token,\\n msg.sender,\\n _amount,\\n _execLayerData\\n );\\n\\n inputBox.addInput(_dapp, input);\\n }\\n}\\n\",\"keccak256\":\"0xe89481452c8fdf15c6c53f78117f56c08a91ac780d06103bec4815d5281e9d7b\",\"license\":\"Apache-2.0\"},\"contracts/portals/IERC20Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IPortal} from \\\"./IPortal.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title ERC-20 Portal interface\\ninterface IERC20Portal is IPortal {\\n // Permissionless functions\\n\\n /// @notice Transfer ERC-20 tokens to a DApp and add an input to\\n /// the DApp's input box to signal such operation.\\n ///\\n /// The caller must allow the portal to withdraw at least `_amount` tokens\\n /// from their account beforehand, by calling the `approve` function in the\\n /// token contract.\\n ///\\n /// @param _token The ERC-20 token contract\\n /// @param _dapp The address of the DApp\\n /// @param _amount The amount of tokens to be transferred\\n /// @param _execLayerData Additional data to be interpreted by the execution layer\\n function depositERC20Tokens(\\n IERC20 _token,\\n address _dapp,\\n uint256 _amount,\\n bytes calldata _execLayerData\\n ) external;\\n}\\n\",\"keccak256\":\"0xdb22270abd94cd3f3f50cac9dbe095f856d38670cb26c2597d5ba823f5935278\",\"license\":\"Apache-2.0\"},\"contracts/portals/IPortal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Portal interface\\ninterface IPortal {\\n // Permissionless functions\\n\\n /// @notice Get the input box used by this portal.\\n /// @return The input box\\n function getInputBox() external view returns (IInputBox);\\n}\\n\",\"keccak256\":\"0x4033ed4fe6845ea5735b9d610c5c426d01cbec3d5164d00ce9842c77d7b6aa8e\",\"license\":\"Apache-2.0\"},\"contracts/portals/Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IPortal} from \\\"./IPortal.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Portal\\n/// @notice This contract serves as a base for all the other portals.\\ncontract Portal is IPortal {\\n /// @notice The input box used by the portal.\\n IInputBox internal immutable inputBox;\\n\\n /// @notice Constructs the portal.\\n /// @param _inputBox The input box used by the portal\\n constructor(IInputBox _inputBox) {\\n inputBox = _inputBox;\\n }\\n\\n function getInputBox() external view override returns (IInputBox) {\\n return inputBox;\\n }\\n}\\n\",\"keccak256\":\"0x7a1715513f7adafd8998a2bab69aef8c06f7456cefcc2100f9bf8e16f01b785e\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161045f38038061045f83398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516103ce61009160003960008181603c015261013501526103ce6000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062aace9a1461003a57806395854b8114610077575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a610085366004610209565b61008c565b005b6040516323b872dd60e01b81523360048201526001600160a01b03858116602483015260448201859052600091908716906323b872dd906064016020604051808303816000875af11580156100e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010991906102a8565b9050600061011b8288338888886101b9565b604051631789cd6360e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631789cd639061016c90899085906004016102d1565b6020604051808303816000875af115801561018b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101af919061032f565b5050505050505050565b60608686868686866040516020016101d696959493929190610348565b60405160208183030381529060405290509695505050505050565b6001600160a01b038116811461020657600080fd5b50565b60008060008060006080868803121561022157600080fd5b853561022c816101f1565b9450602086013561023c816101f1565b935060408601359250606086013567ffffffffffffffff8082111561026057600080fd5b818801915088601f83011261027457600080fd5b81358181111561028357600080fd5b89602082850101111561029557600080fd5b9699959850939650602001949392505050565b6000602082840312156102ba57600080fd5b815180151581146102ca57600080fd5b9392505050565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561030d578581018301518582016060015282016102f1565b506000606082860101526060601f19601f830116850101925050509392505050565b60006020828403121561034157600080fd5b5051919050565b86151560f81b815260006bffffffffffffffffffffffff19808860601b166001840152808760601b166015840152508460298301528284604984013750600091016049019081529594505050505056fea264697066735822122050b5819889408b2d1aed09ead1961cc5188efa933c68ede1ae413d96ed854d1c64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062aace9a1461003a57806395854b8114610077575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a610085366004610209565b61008c565b005b6040516323b872dd60e01b81523360048201526001600160a01b03858116602483015260448201859052600091908716906323b872dd906064016020604051808303816000875af11580156100e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010991906102a8565b9050600061011b8288338888886101b9565b604051631789cd6360e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631789cd639061016c90899085906004016102d1565b6020604051808303816000875af115801561018b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101af919061032f565b5050505050505050565b60608686868686866040516020016101d696959493929190610348565b60405160208183030381529060405290509695505050505050565b6001600160a01b038116811461020657600080fd5b50565b60008060008060006080868803121561022157600080fd5b853561022c816101f1565b9450602086013561023c816101f1565b935060408601359250606086013567ffffffffffffffff8082111561026057600080fd5b818801915088601f83011261027457600080fd5b81358181111561028357600080fd5b89602082850101111561029557600080fd5b9699959850939650602001949392505050565b6000602082840312156102ba57600080fd5b815180151581146102ca57600080fd5b9392505050565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561030d578581018301518582016060015282016102f1565b506000606082860101526060601f19601f830116850101925050509392505050565b60006020828403121561034157600080fd5b5051919050565b86151560f81b815260006bffffffffffffffffffffffff19808860601b166001840152808760601b166015840152508460298301528284604984013750600091016049019081529594505050505056fea264697066735822122050b5819889408b2d1aed09ead1961cc5188efa933c68ede1ae413d96ed854d1c64736f6c63430008130033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_inputBox": "The input box used by the portal" + } + }, + "depositERC20Tokens(address,address,uint256,bytes)": { + "params": { + "_amount": "The amount of tokens to be transferred", + "_dapp": "The address of the DApp", + "_execLayerData": "Additional data to be interpreted by the execution layer", + "_token": "The ERC-20 token contract" + } + }, + "getInputBox()": { + "returns": { + "_0": "The input box" + } + } + }, + "title": "ERC-20 Portal", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Constructs the portal." + }, + "depositERC20Tokens(address,address,uint256,bytes)": { + "notice": "Transfer ERC-20 tokens to a DApp and add an input to the DApp's input box to signal such operation. The caller must allow the portal to withdraw at least `_amount` tokens from their account beforehand, by calling the `approve` function in the token contract." + }, + "getInputBox()": { + "notice": "Get the input box used by this portal." + } + }, + "notice": "This contract allows anyone to perform transfers of ERC-20 tokens to a DApp while informing the off-chain machine.", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/localhost/ERC20PortalFacet.json b/deployments/localhost/ERC20PortalFacet.json deleted file mode 100644 index c2e38cc..0000000 --- a/deployments/localhost/ERC20PortalFacet.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "address": "0x0328426f3cf581F1Cf5Ba3492a3d1C5AB551de62", - "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": "0x3dafcc6b8acde08ea81f1f6cbb2ea632b1d327cc6e07fa285995d214fe7d6cd1", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "480902", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5650fcf5aca90e349e9017441737e8b899a5bdc5332fb65efc9ac517cb537a00", - "transactionHash": "0x3dafcc6b8acde08ea81f1f6cbb2ea632b1d327cc6e07fa285995d214fe7d6cd1", - "logs": [], - "blockNumber": 19, - "cumulativeGasUsed": "480902", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063cb1061a614610030575b600080fd5b61004361003e36600461053b565b610055565b60405190815260200160405180910390f35b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6040516323b872dd60e01b81523360048201523060248201526044810187905290915086906001600160a01b038216906323b872dd906064016020604051808303816000875af11580156100d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f591906105d0565b6101465760405162461bcd60e51b815260206004820152601960248201527f4552433230207472616e7366657246726f6d206661696c65640000000000000060448201526064015b60405180910390fd5b60007f59da2a984e165ae4487c99e5d1dca7e04c8a99301be6bc092932cb5d7f03437833898989896040516020016101839695949392919061061b565b60405160208183030381529060405290507f29e6a9ed1b00933e0de5679ea9bc6ad323969a70b69b627425b46ac0431c7b0188338989896040516101cb959493929190610655565b60405180910390a16101dd83826101e9565b98975050505050505050565b60006101f68383306101fd565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156102775760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640161013d565b610280816103a2565b1561028e5761028e8561047a565b600085600301546000146102a557856001016102a7565b855b905060006102b483610499565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161035991906106aa565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161038d939291906106c1565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103ca576103ca61072d565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156103fb576103fb61072d565b148015610410575061040d8183610743565b42115b1561046f576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161045c9161075b565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561048b57600061048e565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105055761050561072d565b9050600081600281111561051b5761051b61072d565b146105305761052b826001610743565b610532565b815b95945050505050565b6000806000806060858703121561055157600080fd5b84356001600160a01b038116811461056857600080fd5b935060208501359250604085013567ffffffffffffffff8082111561058c57600080fd5b818701915087601f8301126105a057600080fd5b8135818111156105af57600080fd5b8860208285010111156105c157600080fd5b95989497505060200194505050565b6000602082840312156105e257600080fd5b815180151581146101f657600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8681526001600160a01b038681166020830152851660408201526060810184905260a0608082018190526000906101dd90830184866105f2565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061068990830184866105f2565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156106bc576106bc610694565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610703578581018301518582016080015282016106e7565b81811115610715576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b6000821982111561075657610756610694565b500190565b602081016003831061077d57634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212205a6d7e95e471f4059b0981b363bccb6296e05bfe58ac6244f725c2fd38ee94ab64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063cb1061a614610030575b600080fd5b61004361003e36600461053b565b610055565b60405190815260200160405180910390f35b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6040516323b872dd60e01b81523360048201523060248201526044810187905290915086906001600160a01b038216906323b872dd906064016020604051808303816000875af11580156100d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f591906105d0565b6101465760405162461bcd60e51b815260206004820152601960248201527f4552433230207472616e7366657246726f6d206661696c65640000000000000060448201526064015b60405180910390fd5b60007f59da2a984e165ae4487c99e5d1dca7e04c8a99301be6bc092932cb5d7f03437833898989896040516020016101839695949392919061061b565b60405160208183030381529060405290507f29e6a9ed1b00933e0de5679ea9bc6ad323969a70b69b627425b46ac0431c7b0188338989896040516101cb959493929190610655565b60405180910390a16101dd83826101e9565b98975050505050505050565b60006101f68383306101fd565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156102775760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640161013d565b610280816103a2565b1561028e5761028e8561047a565b600085600301546000146102a557856001016102a7565b855b905060006102b483610499565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161035991906106aa565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161038d939291906106c1565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103ca576103ca61072d565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156103fb576103fb61072d565b148015610410575061040d8183610743565b42115b1561046f576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f9161045c9161075b565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561048b57600061048e565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105055761050561072d565b9050600081600281111561051b5761051b61072d565b146105305761052b826001610743565b610532565b815b95945050505050565b6000806000806060858703121561055157600080fd5b84356001600160a01b038116811461056857600080fd5b935060208501359250604085013567ffffffffffffffff8082111561058c57600080fd5b818701915087601f8301126105a057600080fd5b8135818111156105af57600080fd5b8860208285010111156105c157600080fd5b95989497505060200194505050565b6000602082840312156105e257600080fd5b815180151581146101f657600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8681526001600160a01b038681166020830152851660408201526060810184905260a0608082018190526000906101dd90830184866105f2565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061068990830184866105f2565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156106bc576106bc610694565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015610703578581018301518582016080015282016106e7565b81811115610715576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b6000821982111561075657610756610694565b500190565b602081016003831061077d57634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212205a6d7e95e471f4059b0981b363bccb6296e05bfe58ac6244f725c2fd38ee94ab64736f6c634300080d0033", - "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/deployments/localhost/ERC721Portal.json b/deployments/localhost/ERC721Portal.json new file mode 100644 index 0000000..98da08a --- /dev/null +++ b/deployments/localhost/ERC721Portal.json @@ -0,0 +1,132 @@ +{ + "address": "0x4CA354590EB934E6094Be762b38dE75d1Dd605a9", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IInputBox", + "name": "_inputBox", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "contract IERC721", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_dapp", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_baseLayerData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_execLayerData", + "type": "bytes" + } + ], + "name": "depositERC721Token", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getInputBox", + "outputs": [ + { + "internalType": "contract IInputBox", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x553b58faf1db864b93a29eb23ed1526f8cc04d3fddf90863325394c757c63a0c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "308450", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x5e8cc351721f3fa8e7dc9569dacd59f2e84dc429cff545f5a695371f6972310e", + "transactionHash": "0x553b58faf1db864b93a29eb23ed1526f8cc04d3fddf90863325394c757c63a0c", + "logs": [], + "blockNumber": 16, + "cumulativeGasUsed": "308450", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5a723220579C0DCb8C9253E6b4c62e572E379945" + ], + "numDeployments": 1, + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"_inputBox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"contract IERC721\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_baseLayerData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_execLayerData\",\"type\":\"bytes\"}],\"name\":\"depositERC721Token\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputBox\",\"outputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_inputBox\":\"The input box used by the portal\"}},\"depositERC721Token(address,address,uint256,bytes,bytes)\":{\"params\":{\"_baseLayerData\":\"Additional data to be interpreted by the base layer\",\"_dapp\":\"The address of the DApp\",\"_execLayerData\":\"Additional data to be interpreted by the execution layer\",\"_token\":\"The ERC-721 token contract\",\"_tokenId\":\"The identifier of the token being transferred\"}},\"getInputBox()\":{\"returns\":{\"_0\":\"The input box\"}}},\"title\":\"ERC-721 Portal\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructs the portal.\"},\"depositERC721Token(address,address,uint256,bytes,bytes)\":{\"notice\":\"Transfer an ERC-721 token to a DApp and add an input to the DApp's input box to signal such operation. The caller must change the approved address for the ERC-721 token to the portal address beforehand, by calling the `approve` function in the token contract.\"},\"getInputBox()\":{\"notice\":\"Get the input box used by this portal.\"}},\"notice\":\"This contract allows anyone to perform transfers of ERC-721 tokens to a DApp while informing the off-chain machine.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/portals/ERC721Portal.sol\":\"ERC721Portal\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n /**\\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n */\\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\\n\\n /**\\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n * transfers.\\n */\\n event TransferBatch(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256[] ids,\\n uint256[] values\\n );\\n\\n /**\\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n * `approved`.\\n */\\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\\n\\n /**\\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n *\\n * If an {URI} event was emitted for `id`, the standard\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n * returned by {IERC1155MetadataURI-uri}.\\n */\\n event URI(string value, uint256 indexed id);\\n\\n /**\\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(address account, uint256 id) external view returns (uint256);\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\\n external\\n view\\n returns (uint256[] memory);\\n\\n /**\\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n *\\n * Emits an {ApprovalForAll} event.\\n *\\n * Requirements:\\n *\\n * - `operator` cannot be the caller.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n *\\n * See {setApprovalForAll}.\\n */\\n function isApprovedForAll(address account, address operator) external view returns (bool);\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes calldata data\\n ) external;\\n}\\n\",\"keccak256\":\"0x6392f2cfe3a5ee802227fe7a2dfd47096d881aec89bddd214b35c5b46d3cd941\",\"license\":\"MIT\"},\"@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.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"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/common/InputEncoding.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC1155} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/// @title Input Encoding Library\\n\\n/// @notice Defines the encoding of inputs added by core trustless and\\n/// permissionless contracts, such as portals and relays.\\nlibrary InputEncoding {\\n /// @notice Encode an Ether deposit.\\n /// @param sender The Ether sender\\n /// @param value The amount of Ether being sent in Wei\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeEtherDeposit(\\n address sender,\\n uint256 value,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n sender, // 20B\\n value, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-20 token deposit.\\n /// @param ret The return value of `transferFrom`\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param amount The amount of tokens being sent\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeERC20Deposit(\\n bool ret,\\n IERC20 token,\\n address sender,\\n uint256 amount,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n ret, // 1B\\n token, // 20B\\n sender, // 20B\\n amount, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-721 token deposit.\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param tokenId The token identifier\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeERC721Deposit(\\n IERC721 token,\\n address sender,\\n uint256 tokenId,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 single token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenId The identifier of the token being transferred\\n /// @param value Transfer amount\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeSingleERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256 tokenId,\\n uint256 value,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n value, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 batch token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenIds The identifiers of the tokens being transferred\\n /// @param values Transfer amounts per token type\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeBatchERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256[] calldata tokenIds,\\n uint256[] calldata values,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(\\n tokenIds,\\n values,\\n baseLayerData,\\n execLayerData\\n );\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode a DApp address relay.\\n /// @param dapp The DApp address\\n /// @return The encoded input\\n function encodeDAppAddressRelay(\\n address dapp\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n dapp // 20B\\n );\\n }\\n}\\n\",\"keccak256\":\"0x5c60933c8ac9f98004fde0748aee3561effb471eaa52898773dedf6fc5b7eb9e\",\"license\":\"Apache-2.0\"},\"contracts/inputs/IInputBox.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Input Box interface\\ninterface IInputBox {\\n /// @notice Emitted when an input is added to a DApp's input box.\\n /// @param dapp The address of the DApp\\n /// @param inboxInputIndex The index of the input in the input box\\n /// @param sender The address that sent the input\\n /// @param input The contents of the input\\n /// @dev MUST be triggered on a successful call to `addInput`.\\n event InputAdded(\\n address indexed dapp,\\n uint256 indexed inboxInputIndex,\\n address sender,\\n bytes input\\n );\\n\\n /// @notice Add an input to a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _input The contents of the input\\n /// @return The hash of the input plus some extra metadata\\n /// @dev MUST fire an `InputAdded` event accordingly.\\n function addInput(\\n address _dapp,\\n bytes calldata _input\\n ) external returns (bytes32);\\n\\n /// @notice Get the number of inputs in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @return Number of inputs in the DApp's input box\\n function getNumberOfInputs(address _dapp) external view returns (uint256);\\n\\n /// @notice Get the hash of an input in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _index The index of the input in the DApp's input box\\n /// @return The hash of the input at the provided index in the DApp's input box\\n /// @dev `_index` MUST be in the interval `[0,n)` where `n` is the number of\\n /// inputs in the DApp's input box. See the `getNumberOfInputs` function.\\n function getInputHash(\\n address _dapp,\\n uint256 _index\\n ) external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x2addd467a24cde2131784103080aeb28df40d87ba19c5fd92bf96c0c074603df\",\"license\":\"Apache-2.0\"},\"contracts/portals/ERC721Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\nimport {IERC721Portal} from \\\"./IERC721Portal.sol\\\";\\nimport {Portal} from \\\"./Portal.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\nimport {InputEncoding} from \\\"../common/InputEncoding.sol\\\";\\n\\n/// @title ERC-721 Portal\\n///\\n/// @notice This contract allows anyone to perform transfers of\\n/// ERC-721 tokens to a DApp while informing the off-chain machine.\\ncontract ERC721Portal is Portal, IERC721Portal {\\n /// @notice Constructs the portal.\\n /// @param _inputBox The input box used by the portal\\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\\n\\n function depositERC721Token(\\n IERC721 _token,\\n address _dapp,\\n uint256 _tokenId,\\n bytes calldata _baseLayerData,\\n bytes calldata _execLayerData\\n ) external override {\\n _token.safeTransferFrom(msg.sender, _dapp, _tokenId, _baseLayerData);\\n\\n bytes memory input = InputEncoding.encodeERC721Deposit(\\n _token,\\n msg.sender,\\n _tokenId,\\n _baseLayerData,\\n _execLayerData\\n );\\n\\n inputBox.addInput(_dapp, input);\\n }\\n}\\n\",\"keccak256\":\"0xae42ba0ffe633ffcae0f7468eb93edf03d64b3532e88bd8a6d493a5e475dd6a5\",\"license\":\"Apache-2.0\"},\"contracts/portals/IERC721Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IPortal} from \\\"./IPortal.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Portal interface\\ninterface IERC721Portal is IPortal {\\n // Permissionless functions\\n\\n /// @notice Transfer an ERC-721 token to a DApp and add an input to\\n /// the DApp's input box to signal such operation.\\n ///\\n /// The caller must change the approved address for the ERC-721 token\\n /// to the portal address beforehand, by calling the `approve` function in the\\n /// token contract.\\n ///\\n /// @param _token The ERC-721 token contract\\n /// @param _dapp The address of the DApp\\n /// @param _tokenId The identifier of the token being transferred\\n /// @param _baseLayerData Additional data to be interpreted by the base layer\\n /// @param _execLayerData Additional data to be interpreted by the execution layer\\n function depositERC721Token(\\n IERC721 _token,\\n address _dapp,\\n uint256 _tokenId,\\n bytes calldata _baseLayerData,\\n bytes calldata _execLayerData\\n ) external;\\n}\\n\",\"keccak256\":\"0xbb32094aa2c6abb4528590b03f8af85e40cd642bb58e0fa350f520e7d5728ed0\",\"license\":\"Apache-2.0\"},\"contracts/portals/IPortal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Portal interface\\ninterface IPortal {\\n // Permissionless functions\\n\\n /// @notice Get the input box used by this portal.\\n /// @return The input box\\n function getInputBox() external view returns (IInputBox);\\n}\\n\",\"keccak256\":\"0x4033ed4fe6845ea5735b9d610c5c426d01cbec3d5164d00ce9842c77d7b6aa8e\",\"license\":\"Apache-2.0\"},\"contracts/portals/Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IPortal} from \\\"./IPortal.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Portal\\n/// @notice This contract serves as a base for all the other portals.\\ncontract Portal is IPortal {\\n /// @notice The input box used by the portal.\\n IInputBox internal immutable inputBox;\\n\\n /// @notice Constructs the portal.\\n /// @param _inputBox The input box used by the portal\\n constructor(IInputBox _inputBox) {\\n inputBox = _inputBox;\\n }\\n\\n function getInputBox() external view override returns (IInputBox) {\\n return inputBox;\\n }\\n}\\n\",\"keccak256\":\"0x7a1715513f7adafd8998a2bab69aef8c06f7456cefcc2100f9bf8e16f01b785e\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161052438038061052483398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b60805161049361009160003960008181603c015261011d01526104936000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062aace9a1461003a57806328911e8314610077575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a610085366004610263565b61008c565b005b604051635c46a7ef60e11b81526001600160a01b0388169063b88d4fde906100c09033908a908a908a908a9060040161032b565b600060405180830381600087803b1580156100da57600080fd5b505af11580156100ee573d6000803e3d6000fd5b505050506000610103883388888888886101a2565b604051631789cd6360e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631789cd6390610154908a90859060040161038e565b6020604051808303816000875af1158015610173573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019791906103d0565b505050505050505050565b60606000858585856040516020016101bd94939291906103e9565b6040516020818303038152906040529050888888836040516020016101e59493929190610410565b604051602081830303815290604052915050979650505050505050565b6001600160a01b038116811461021757600080fd5b50565b60008083601f84011261022c57600080fd5b50813567ffffffffffffffff81111561024457600080fd5b60208301915083602082850101111561025c57600080fd5b9250929050565b600080600080600080600060a0888a03121561027e57600080fd5b873561028981610202565b9650602088013561029981610202565b955060408801359450606088013567ffffffffffffffff808211156102bd57600080fd5b6102c98b838c0161021a565b909650945060808a01359150808211156102e257600080fd5b506102ef8a828b0161021a565b989b979a50959850939692959293505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061035f9083018486610302565b979650505050505050565b60005b8381101561038557818101518382015260200161036d565b50506000910152565b60018060a01b038316815260406020820152600082518060408401526103bb81606085016020870161036a565b601f01601f1916919091016060019392505050565b6000602082840312156103e257600080fd5b5051919050565b6040815260006103fd604083018688610302565b828103602084015261035f818587610302565b60006bffffffffffffffffffffffff19808760601b168352808660601b16601484015250836028830152825161044d81604885016020870161036a565b919091016048019594505050505056fea2646970667358221220b22dd7950cfd5fd6c7712aa0c8b184fe29c78dd0ccd21d50a55569e489adbc1d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062aace9a1461003a57806328911e8314610077575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a610085366004610263565b61008c565b005b604051635c46a7ef60e11b81526001600160a01b0388169063b88d4fde906100c09033908a908a908a908a9060040161032b565b600060405180830381600087803b1580156100da57600080fd5b505af11580156100ee573d6000803e3d6000fd5b505050506000610103883388888888886101a2565b604051631789cd6360e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631789cd6390610154908a90859060040161038e565b6020604051808303816000875af1158015610173573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019791906103d0565b505050505050505050565b60606000858585856040516020016101bd94939291906103e9565b6040516020818303038152906040529050888888836040516020016101e59493929190610410565b604051602081830303815290604052915050979650505050505050565b6001600160a01b038116811461021757600080fd5b50565b60008083601f84011261022c57600080fd5b50813567ffffffffffffffff81111561024457600080fd5b60208301915083602082850101111561025c57600080fd5b9250929050565b600080600080600080600060a0888a03121561027e57600080fd5b873561028981610202565b9650602088013561029981610202565b955060408801359450606088013567ffffffffffffffff808211156102bd57600080fd5b6102c98b838c0161021a565b909650945060808a01359150808211156102e257600080fd5b506102ef8a828b0161021a565b989b979a50959850939692959293505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061035f9083018486610302565b979650505050505050565b60005b8381101561038557818101518382015260200161036d565b50506000910152565b60018060a01b038316815260406020820152600082518060408401526103bb81606085016020870161036a565b601f01601f1916919091016060019392505050565b6000602082840312156103e257600080fd5b5051919050565b6040815260006103fd604083018688610302565b828103602084015261035f818587610302565b60006bffffffffffffffffffffffff19808760601b168352808660601b16601484015250836028830152825161044d81604885016020870161036a565b919091016048019594505050505056fea2646970667358221220b22dd7950cfd5fd6c7712aa0c8b184fe29c78dd0ccd21d50a55569e489adbc1d64736f6c63430008130033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_inputBox": "The input box used by the portal" + } + }, + "depositERC721Token(address,address,uint256,bytes,bytes)": { + "params": { + "_baseLayerData": "Additional data to be interpreted by the base layer", + "_dapp": "The address of the DApp", + "_execLayerData": "Additional data to be interpreted by the execution layer", + "_token": "The ERC-721 token contract", + "_tokenId": "The identifier of the token being transferred" + } + }, + "getInputBox()": { + "returns": { + "_0": "The input box" + } + } + }, + "title": "ERC-721 Portal", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Constructs the portal." + }, + "depositERC721Token(address,address,uint256,bytes,bytes)": { + "notice": "Transfer an ERC-721 token to a DApp and add an input to the DApp's input box to signal such operation. The caller must change the approved address for the ERC-721 token to the portal address beforehand, by calling the `approve` function in the token contract." + }, + "getInputBox()": { + "notice": "Get the input box used by this portal." + } + }, + "notice": "This contract allows anyone to perform transfers of ERC-721 tokens to a DApp while informing the off-chain machine.", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/localhost/ERC721PortalFacet.json b/deployments/localhost/ERC721PortalFacet.json deleted file mode 100644 index 197341d..0000000 --- a/deployments/localhost/ERC721PortalFacet.json +++ /dev/null @@ -1,190 +0,0 @@ -{ - "address": "0xCF8E4cb394805b96290FEcE429E98613aB80b1c3", - "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": "0x74b6507c17bf312d2e0546c2014533ac5f480cb66ca4a5696c960013c3988ac1", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "556226", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xce70da3e8e68c53ee0cd8e9315d8c18e987f282e38676af7052c6bee143ff87c", - "transactionHash": "0x74b6507c17bf312d2e0546c2014533ac5f480cb66ca4a5696c960013c3988ac1", - "logs": [], - "blockNumber": 20, - "cumulativeGasUsed": "556226", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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.7.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 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\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"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(\\n bytes calldata _data\\n ) public override returns (bool) {\\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\":\"0xbd1cd5ef628fd33a3684a191ffd12dc66144031399a33e5886aea6878c36b420\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610915806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063150b7a021461003b57806315e55ce51461006c575b600080fd5b61004e61004936600461063a565b61008f565b6040516001600160e01b031990911681526020015b60405180910390f35b61007f61007a3660046106ad565b610168565b6040519015158152602001610063565b6040516000907f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff90339083906100f5907f64d9de45e7db1c0a7cb7960ad25107a6379b6ab85b30444f3a8d724857c1ac789084908c908c908c908c908c90602001610718565b60408051601f1981840301815291905290506101118382610287565b507f33dcfebf3eaf42764314a95335af55bb1c008027c47c827e6e09119071639e1d828a8a8a8a8a60405161014b96959493929190610767565b60405180910390a150630a85bd0160e11b98975050505050505050565b60003330146101ac5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080806101bc858701876107af565b604051632142170760e11b81523060048201526001600160a01b03808416602483015260448201839052939650919450925084918216906342842e0e90606401600060405180830381600087803b15801561021657600080fd5b505af115801561022a573d6000803e3d6000fd5b5050604080516001600160a01b038089168252871660208201529081018590527feea167c0d54572a80626f5fd092a7c1f7b5d8e309533747e7e7d77b0558d6cf19250606001905060405180910390a15060019695505050505050565b600061029483833061029b565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156103155760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d000000000000000060448201526064016101a3565b61031e81610440565b1561032c5761032c85610518565b600085600301546000146103435785600101610345565b855b9050600061035283610537565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f79190610806565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161042b9392919061081d565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff16600281111561046857610468610889565b600184015490915063ffffffff68010000000000000000820481169116600083600281111561049957610499610889565b1480156104ae57506104ab818361089f565b42115b1561050d576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104fa916108b7565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561052957600061052c565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105a3576105a3610889565b905060008160028111156105b9576105b9610889565b146105ce576105c982600161089f565b6105d0565b815b95945050505050565b6001600160a01b03811681146105ee57600080fd5b50565b60008083601f84011261060357600080fd5b50813567ffffffffffffffff81111561061b57600080fd5b60208301915083602082850101111561063357600080fd5b9250929050565b60008060008060006080868803121561065257600080fd5b853561065d816105d9565b9450602086013561066d816105d9565b935060408601359250606086013567ffffffffffffffff81111561069057600080fd5b61069c888289016105f1565b969995985093965092949392505050565b600080602083850312156106c057600080fd5b823567ffffffffffffffff8111156106d757600080fd5b6106e3858286016105f1565b90969095509350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b0387811660208301528681166040830152851660608201526080810184905260c060a0820181905260009061075a90830184866106ef565b9998505050505050505050565b6001600160a01b0387811682528681166020830152851660408201526060810184905260a0608082018190526000906107a390830184866106ef565b98975050505050505050565b6000806000606084860312156107c457600080fd5b83356107cf816105d9565b925060208401356107df816105d9565b929592945050506040919091013590565b634e487b7160e01b600052601160045260246000fd5b600082821015610818576108186107f0565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561085f57858101830151858201608001528201610843565b81811115610871576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156108b2576108b26107f0565b500190565b60208101600383106108d957634e487b7160e01b600052602160045260246000fd5b9190529056fea2646970667358221220ada45102ca8542269d607ca3adc88e35886a8c2ebeb4598d141e42101f76ec9664736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063150b7a021461003b57806315e55ce51461006c575b600080fd5b61004e61004936600461063a565b61008f565b6040516001600160e01b031990911681526020015b60405180910390f35b61007f61007a3660046106ad565b610168565b6040519015158152602001610063565b6040516000907f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff90339083906100f5907f64d9de45e7db1c0a7cb7960ad25107a6379b6ab85b30444f3a8d724857c1ac789084908c908c908c908c908c90602001610718565b60408051601f1981840301815291905290506101118382610287565b507f33dcfebf3eaf42764314a95335af55bb1c008027c47c827e6e09119071639e1d828a8a8a8a8a60405161014b96959493929190610767565b60405180910390a150630a85bd0160e11b98975050505050505050565b60003330146101ac5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080806101bc858701876107af565b604051632142170760e11b81523060048201526001600160a01b03808416602483015260448201839052939650919450925084918216906342842e0e90606401600060405180830381600087803b15801561021657600080fd5b505af115801561022a573d6000803e3d6000fd5b5050604080516001600160a01b038089168252871660208201529081018590527feea167c0d54572a80626f5fd092a7c1f7b5d8e309533747e7e7d77b0558d6cf19250606001905060405180910390a15060019695505050505050565b600061029483833061029b565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c9111156103155760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d000000000000000060448201526064016101a3565b61031e81610440565b1561032c5761032c85610518565b600085600301546000146103435785600101610345565b855b9050600061035283610537565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f79190610806565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d60405161042b9392919061081d565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff16600281111561046857610468610889565b600184015490915063ffffffff68010000000000000000820481169116600083600281111561049957610499610889565b1480156104ae57506104ab818361089f565b42115b1561050d576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104fa916108b7565b60405180910390a1506001949350505050565b506000949350505050565b60038101541561052957600061052c565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff1660028111156105a3576105a3610889565b905060008160028111156105b9576105b9610889565b146105ce576105c982600161089f565b6105d0565b815b95945050505050565b6001600160a01b03811681146105ee57600080fd5b50565b60008083601f84011261060357600080fd5b50813567ffffffffffffffff81111561061b57600080fd5b60208301915083602082850101111561063357600080fd5b9250929050565b60008060008060006080868803121561065257600080fd5b853561065d816105d9565b9450602086013561066d816105d9565b935060408601359250606086013567ffffffffffffffff81111561069057600080fd5b61069c888289016105f1565b969995985093965092949392505050565b600080602083850312156106c057600080fd5b823567ffffffffffffffff8111156106d757600080fd5b6106e3858286016105f1565b90969095509350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b0387811660208301528681166040830152851660608201526080810184905260c060a0820181905260009061075a90830184866106ef565b9998505050505050505050565b6001600160a01b0387811682528681166020830152851660408201526060810184905260a0608082018190526000906107a390830184866106ef565b98975050505050505050565b6000806000606084860312156107c457600080fd5b83356107cf816105d9565b925060208401356107df816105d9565b929592945050506040919091013590565b634e487b7160e01b600052601160045260246000fd5b600082821015610818576108186107f0565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561085f57858101830151858201608001528201610843565b81811115610871576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156108b2576108b26107f0565b500190565b60208101600383106108d957634e487b7160e01b600052602160045260246000fd5b9190529056fea2646970667358221220ada45102ca8542269d607ca3adc88e35886a8c2ebeb4598d141e42101f76ec9664736f6c634300080d0033", - "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/deployments/localhost/EtherPortal.json b/deployments/localhost/EtherPortal.json new file mode 100644 index 0000000..2cc5619 --- /dev/null +++ b/deployments/localhost/EtherPortal.json @@ -0,0 +1,114 @@ +{ + "address": "0xA89A3216F46F66486C9B794C1e28d3c44D59591e", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IInputBox", + "name": "_inputBox", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dapp", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_execLayerData", + "type": "bytes" + } + ], + "name": "depositEther", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getInputBox", + "outputs": [ + { + "internalType": "contract IInputBox", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x82ee1302f8f1f96122863a20659df61212ddfcd2f9b4e54de38c6e7da32d682c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "248940", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd3fdf53afe007c0b10df725499ef293025787c261f83f4083969e6b2caa724a7", + "transactionHash": "0x82ee1302f8f1f96122863a20659df61212ddfcd2f9b4e54de38c6e7da32d682c", + "logs": [], + "blockNumber": 14, + "cumulativeGasUsed": "248940", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5a723220579C0DCb8C9253E6b4c62e572E379945" + ], + "numDeployments": 1, + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"_inputBox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execLayerData\",\"type\":\"bytes\"}],\"name\":\"depositEther\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInputBox\",\"outputs\":[{\"internalType\":\"contract IInputBox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_inputBox\":\"The input box used by the portal\"}},\"depositEther(address,bytes)\":{\"params\":{\"_dapp\":\"The address of the DApp\",\"_execLayerData\":\"Additional data to be interpreted by the execution layer\"}},\"getInputBox()\":{\"returns\":{\"_0\":\"The input box\"}}},\"title\":\"Ether Portal\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructs the portal.\"},\"depositEther(address,bytes)\":{\"notice\":\"Transfer Ether to a DApp and add an input to the DApp's input box to signal such operation. All the value sent through this function is forwarded to the DApp.\"},\"getInputBox()\":{\"notice\":\"Get the input box used by this portal.\"}},\"notice\":\"This contract allows anyone to perform transfers of Ether to a DApp while informing the off-chain machine.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/portals/EtherPortal.sol\":\"EtherPortal\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n /**\\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n */\\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\\n\\n /**\\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n * transfers.\\n */\\n event TransferBatch(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256[] ids,\\n uint256[] values\\n );\\n\\n /**\\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n * `approved`.\\n */\\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\\n\\n /**\\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n *\\n * If an {URI} event was emitted for `id`, the standard\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n * returned by {IERC1155MetadataURI-uri}.\\n */\\n event URI(string value, uint256 indexed id);\\n\\n /**\\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(address account, uint256 id) external view returns (uint256);\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\\n external\\n view\\n returns (uint256[] memory);\\n\\n /**\\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n *\\n * Emits an {ApprovalForAll} event.\\n *\\n * Requirements:\\n *\\n * - `operator` cannot be the caller.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n *\\n * See {setApprovalForAll}.\\n */\\n function isApprovedForAll(address account, address operator) external view returns (bool);\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes calldata data\\n ) external;\\n}\\n\",\"keccak256\":\"0x6392f2cfe3a5ee802227fe7a2dfd47096d881aec89bddd214b35c5b46d3cd941\",\"license\":\"MIT\"},\"@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.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"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/common/InputEncoding.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC1155} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/// @title Input Encoding Library\\n\\n/// @notice Defines the encoding of inputs added by core trustless and\\n/// permissionless contracts, such as portals and relays.\\nlibrary InputEncoding {\\n /// @notice Encode an Ether deposit.\\n /// @param sender The Ether sender\\n /// @param value The amount of Ether being sent in Wei\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeEtherDeposit(\\n address sender,\\n uint256 value,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n sender, // 20B\\n value, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-20 token deposit.\\n /// @param ret The return value of `transferFrom`\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param amount The amount of tokens being sent\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n function encodeERC20Deposit(\\n bool ret,\\n IERC20 token,\\n address sender,\\n uint256 amount,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n ret, // 1B\\n token, // 20B\\n sender, // 20B\\n amount, // 32B\\n execLayerData // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-721 token deposit.\\n /// @param token The token contract\\n /// @param sender The token sender\\n /// @param tokenId The token identifier\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeERC721Deposit(\\n IERC721 token,\\n address sender,\\n uint256 tokenId,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 single token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenId The identifier of the token being transferred\\n /// @param value Transfer amount\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeSingleERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256 tokenId,\\n uint256 value,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(baseLayerData, execLayerData);\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n tokenId, // 32B\\n value, // 32B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode an ERC-1155 batch token deposit.\\n /// @param token The ERC-1155 token contract\\n /// @param sender The token sender\\n /// @param tokenIds The identifiers of the tokens being transferred\\n /// @param values Transfer amounts per token type\\n /// @param baseLayerData Additional data to be interpreted by the base layer\\n /// @param execLayerData Additional data to be interpreted by the execution layer\\n /// @return The encoded input\\n /// @dev `baseLayerData` should be forwarded to `token`.\\n function encodeBatchERC1155Deposit(\\n IERC1155 token,\\n address sender,\\n uint256[] calldata tokenIds,\\n uint256[] calldata values,\\n bytes calldata baseLayerData,\\n bytes calldata execLayerData\\n ) internal pure returns (bytes memory) {\\n bytes memory data = abi.encode(\\n tokenIds,\\n values,\\n baseLayerData,\\n execLayerData\\n );\\n return\\n abi.encodePacked(\\n token, // 20B\\n sender, // 20B\\n data // arbitrary size\\n );\\n }\\n\\n /// @notice Encode a DApp address relay.\\n /// @param dapp The DApp address\\n /// @return The encoded input\\n function encodeDAppAddressRelay(\\n address dapp\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodePacked(\\n dapp // 20B\\n );\\n }\\n}\\n\",\"keccak256\":\"0x5c60933c8ac9f98004fde0748aee3561effb471eaa52898773dedf6fc5b7eb9e\",\"license\":\"Apache-2.0\"},\"contracts/inputs/IInputBox.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Input Box interface\\ninterface IInputBox {\\n /// @notice Emitted when an input is added to a DApp's input box.\\n /// @param dapp The address of the DApp\\n /// @param inboxInputIndex The index of the input in the input box\\n /// @param sender The address that sent the input\\n /// @param input The contents of the input\\n /// @dev MUST be triggered on a successful call to `addInput`.\\n event InputAdded(\\n address indexed dapp,\\n uint256 indexed inboxInputIndex,\\n address sender,\\n bytes input\\n );\\n\\n /// @notice Add an input to a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _input The contents of the input\\n /// @return The hash of the input plus some extra metadata\\n /// @dev MUST fire an `InputAdded` event accordingly.\\n function addInput(\\n address _dapp,\\n bytes calldata _input\\n ) external returns (bytes32);\\n\\n /// @notice Get the number of inputs in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @return Number of inputs in the DApp's input box\\n function getNumberOfInputs(address _dapp) external view returns (uint256);\\n\\n /// @notice Get the hash of an input in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _index The index of the input in the DApp's input box\\n /// @return The hash of the input at the provided index in the DApp's input box\\n /// @dev `_index` MUST be in the interval `[0,n)` where `n` is the number of\\n /// inputs in the DApp's input box. See the `getNumberOfInputs` function.\\n function getInputHash(\\n address _dapp,\\n uint256 _index\\n ) external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x2addd467a24cde2131784103080aeb28df40d87ba19c5fd92bf96c0c074603df\",\"license\":\"Apache-2.0\"},\"contracts/portals/EtherPortal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IEtherPortal} from \\\"./IEtherPortal.sol\\\";\\nimport {Portal} from \\\"./Portal.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\nimport {InputEncoding} from \\\"../common/InputEncoding.sol\\\";\\n\\n/// @title Ether Portal\\n///\\n/// @notice This contract allows anyone to perform transfers of\\n/// Ether to a DApp while informing the off-chain machine.\\ncontract EtherPortal is Portal, IEtherPortal {\\n /// @notice Constructs the portal.\\n /// @param _inputBox The input box used by the portal\\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\\n\\n function depositEther(\\n address _dapp,\\n bytes calldata _execLayerData\\n ) external payable override {\\n // We used to call `transfer()` but it's not considered safe,\\n // as it assumes gas costs are immutable (they are not).\\n (bool success, ) = _dapp.call{value: msg.value}(\\\"\\\");\\n require(success, \\\"EtherPortal: transfer failed\\\");\\n\\n bytes memory input = InputEncoding.encodeEtherDeposit(\\n msg.sender,\\n msg.value,\\n _execLayerData\\n );\\n\\n inputBox.addInput(_dapp, input);\\n }\\n}\\n\",\"keccak256\":\"0x6c3bf707957c24233d9b7d2ba471ddf3c823fd2e0c7898c65a529d5e3440e4fa\",\"license\":\"Apache-2.0\"},\"contracts/portals/IEtherPortal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IPortal} from \\\"./IPortal.sol\\\";\\n\\n/// @title Ether Portal interface\\ninterface IEtherPortal is IPortal {\\n // Permissionless functions\\n\\n /// @notice Transfer Ether to a DApp and add an input to\\n /// the DApp's input box to signal such operation.\\n ///\\n /// All the value sent through this function is forwarded to the DApp.\\n ///\\n /// @param _dapp The address of the DApp\\n /// @param _execLayerData Additional data to be interpreted by the execution layer\\n function depositEther(\\n address _dapp,\\n bytes calldata _execLayerData\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x24945f92cc1f593d51db5e82df31d01f72fa48473c7cde08d6f93915fd3946e3\",\"license\":\"Apache-2.0\"},\"contracts/portals/IPortal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Portal interface\\ninterface IPortal {\\n // Permissionless functions\\n\\n /// @notice Get the input box used by this portal.\\n /// @return The input box\\n function getInputBox() external view returns (IInputBox);\\n}\\n\",\"keccak256\":\"0x4033ed4fe6845ea5735b9d610c5c426d01cbec3d5164d00ce9842c77d7b6aa8e\",\"license\":\"Apache-2.0\"},\"contracts/portals/Portal.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IPortal} from \\\"./IPortal.sol\\\";\\nimport {IInputBox} from \\\"../inputs/IInputBox.sol\\\";\\n\\n/// @title Portal\\n/// @notice This contract serves as a base for all the other portals.\\ncontract Portal is IPortal {\\n /// @notice The input box used by the portal.\\n IInputBox internal immutable inputBox;\\n\\n /// @notice Constructs the portal.\\n /// @param _inputBox The input box used by the portal\\n constructor(IInputBox _inputBox) {\\n inputBox = _inputBox;\\n }\\n\\n function getInputBox() external view override returns (IInputBox) {\\n return inputBox;\\n }\\n}\\n\",\"keccak256\":\"0x7a1715513f7adafd8998a2bab69aef8c06f7456cefcc2100f9bf8e16f01b785e\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161041138038061041183398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b60805161038061009160003960008181603c015261015b01526103806000f3fe6080604052600436106100285760003560e01c8062aace9a1461002d578063938c054f14610077575b600080fd5b34801561003957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a61008536600461020f565b61008c565b005b6000836001600160a01b03163460405160006040518083038185875af1925050503d80600081146100d9576040519150601f19603f3d011682016040523d82523d6000602084013e6100de565b606091505b50509050806101335760405162461bcd60e51b815260206004820152601c60248201527f4574686572506f7274616c3a207472616e73666572206661696c656400000000604482015260640160405180910390fd5b6000610141333486866101dd565b604051631789cd6360e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631789cd639061019290889085906004016102a0565b6020604051808303816000875af11580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d591906102fe565b505050505050565b6060848484846040516020016101f69493929190610317565b6040516020818303038152906040529050949350505050565b60008060006040848603121561022457600080fd5b83356001600160a01b038116811461023b57600080fd5b9250602084013567ffffffffffffffff8082111561025857600080fd5b818601915086601f83011261026c57600080fd5b81358181111561027b57600080fd5b87602082850101111561028d57600080fd5b6020830194508093505050509250925092565b60018060a01b038316815260006020604081840152835180604085015260005b818110156102dc578581018301518582016060015282016102c0565b506000606082860101526060601f19601f830116850101925050509392505050565b60006020828403121561031057600080fd5b5051919050565b6bffffffffffffffffffffffff198560601b1681528360148201528183603483013760009101603401908152939250505056fea26469706673582212201a9c3b3cc643135d14abad471214d58107b280f6f9d4a4dc5c17f9f566bc42e964736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100285760003560e01c8062aace9a1461002d578063938c054f14610077575b600080fd5b34801561003957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b61008a61008536600461020f565b61008c565b005b6000836001600160a01b03163460405160006040518083038185875af1925050503d80600081146100d9576040519150601f19603f3d011682016040523d82523d6000602084013e6100de565b606091505b50509050806101335760405162461bcd60e51b815260206004820152601c60248201527f4574686572506f7274616c3a207472616e73666572206661696c656400000000604482015260640160405180910390fd5b6000610141333486866101dd565b604051631789cd6360e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631789cd639061019290889085906004016102a0565b6020604051808303816000875af11580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d591906102fe565b505050505050565b6060848484846040516020016101f69493929190610317565b6040516020818303038152906040529050949350505050565b60008060006040848603121561022457600080fd5b83356001600160a01b038116811461023b57600080fd5b9250602084013567ffffffffffffffff8082111561025857600080fd5b818601915086601f83011261026c57600080fd5b81358181111561027b57600080fd5b87602082850101111561028d57600080fd5b6020830194508093505050509250925092565b60018060a01b038316815260006020604081840152835180604085015260005b818110156102dc578581018301518582016060015282016102c0565b506000606082860101526060601f19601f830116850101925050509392505050565b60006020828403121561031057600080fd5b5051919050565b6bffffffffffffffffffffffff198560601b1681528360148201528183603483013760009101603401908152939250505056fea26469706673582212201a9c3b3cc643135d14abad471214d58107b280f6f9d4a4dc5c17f9f566bc42e964736f6c63430008130033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_inputBox": "The input box used by the portal" + } + }, + "depositEther(address,bytes)": { + "params": { + "_dapp": "The address of the DApp", + "_execLayerData": "Additional data to be interpreted by the execution layer" + } + }, + "getInputBox()": { + "returns": { + "_0": "The input box" + } + } + }, + "title": "Ether Portal", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Constructs the portal." + }, + "depositEther(address,bytes)": { + "notice": "Transfer Ether to a DApp and add an input to the DApp's input box to signal such operation. All the value sent through this function is forwarded to the DApp." + }, + "getInputBox()": { + "notice": "Get the input box used by this portal." + } + }, + "notice": "This contract allows anyone to perform transfers of Ether to a DApp while informing the off-chain machine.", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/localhost/EtherPortalFacet.json b/deployments/localhost/EtherPortalFacet.json deleted file mode 100644 index 3708cd6..0000000 --- a/deployments/localhost/EtherPortalFacet.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "address": "0x1ab5f2688Faec8Dd89e0E2BF23506dB4A4EE5eCA", - "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": "0x75abcc2e81673ce9536ccb4312da6745837173d9cdf4786ee36555adda72cb35", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "507160", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4bd7b38711bb8c519ac5d071ff97aaad85519064601ca4ee25e2abc47dce256a", - "transactionHash": "0x75abcc2e81673ce9536ccb4312da6745837173d9cdf4786ee36555adda72cb35", - "logs": [], - "blockNumber": 21, - "cumulativeGasUsed": "507160", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n bytes calldata _data\\n ) public payable override returns (bytes32) {\\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(\\n bytes calldata _data\\n ) public override returns (bool) {\\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\":\"0xb60a21f83dc7ccddcac107f89f155b9237dc35fa1ded07896be92a6935c5323a\",\"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(\\n bytes calldata _data\\n ) external payable 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\":\"0xb577c0392786e7be6dcb21608a913abe26476d6d8625075ee6e78310a5b7654e\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610832806100206000396000f3fe6080604052600436106100295760003560e01c80632abfe7b31461002e57806374956b9414610054575b600080fd5b61004161003c3660046105cf565b610084565b6040519081526020015b60405180910390f35b34801561006057600080fd5b5061007461006f3660046105cf565b610146565b604051901515815260200161004b565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905060007ff258e0fc39d35abd7d8393dcfe7e1cf8c745ddca38ae41d451d0c55ac5f2c4ce333487876040516020016100e595949392919061066a565b60405160208183030381529060405290507fa9888e32d8ea552aaeb3018b9c85c77c66ecc61cf8d1989f9e3271a88205ee633334878760405161012b94939291906106a3565b60405180910390a161013d8282610280565b95945050505050565b600033301461018a5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080610199848601866106d5565b915091506000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146101ea576040519150601f19603f3d011682016040523d82523d6000602084013e6101ef565b606091505b50509050806102325760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610181565b604080516001600160a01b0385168152602081018490527f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c910160405180910390a150600195945050505050565b600061028d838330610294565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561030e5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610181565b61031781610439565b156103255761032585610511565b6000856003015460001461033c578560010161033e565b855b9050600061034b83610530565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f09190610723565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516104249392919061073a565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff166002811115610461576104616107a6565b600184015490915063ffffffff680100000000000000008204811691166000836002811115610492576104926107a6565b1480156104a757506104a481836107bc565b42115b15610506576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104f3916107d4565b60405180910390a1506001949350505050565b506000949350505050565b600381015415610522576000610525565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561059c5761059c6107a6565b905060008160028111156105b2576105b26107a6565b146105c7576105c28260016107bc565b61013d565b509392505050565b600080602083850312156105e257600080fd5b823567ffffffffffffffff808211156105fa57600080fd5b818501915085601f83011261060e57600080fd5b81358181111561061d57600080fd5b86602082850101111561062f57600080fd5b60209290920196919550909350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b85815260018060a01b0385166020820152836040820152608060608201526000610698608083018486610641565b979650505050505050565b60018060a01b03851681528360208201526060604082015260006106cb606083018486610641565b9695505050505050565b600080604083850312156106e857600080fd5b82356001600160a01b03811681146106ff57600080fd5b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156107355761073561070d565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561077c57858101830151858201608001528201610760565b8181111561078e576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156107cf576107cf61070d565b500190565b60208101600383106107f657634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212206b62acb6c77dbe7d4d69c04d66b5b6af207e0e940b9d6945a047852bcb79224a64736f6c634300080d0033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80632abfe7b31461002e57806374956b9414610054575b600080fd5b61004161003c3660046105cf565b610084565b6040519081526020015b60405180910390f35b34801561006057600080fd5b5061007461006f3660046105cf565b610146565b604051901515815260200161004b565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905060007ff258e0fc39d35abd7d8393dcfe7e1cf8c745ddca38ae41d451d0c55ac5f2c4ce333487876040516020016100e595949392919061066a565b60405160208183030381529060405290507fa9888e32d8ea552aaeb3018b9c85c77c66ecc61cf8d1989f9e3271a88205ee633334878760405161012b94939291906106a3565b60405180910390a161013d8282610280565b95945050505050565b600033301461018a5760405162461bcd60e51b815260206004820152600b60248201526a37b7363c9034ba39b2b63360a91b60448201526064015b60405180910390fd5b600080610199848601866106d5565b915091506000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146101ea576040519150601f19603f3d011682016040523d82523d6000602084013e6101ef565b606091505b50509050806102325760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610181565b604080516001600160a01b0385168152602081018490527f06097061aeda806b5e9cb4133d9899f332ff0913956567fc0f7ea15e3d19947c910160405180910390a150600195945050505050565b600061028d838330610294565b9392505050565b600283015482516000917fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c91111561030e5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d00000000000000006044820152606401610181565b61031781610439565b156103255761032585610511565b6000856003015460001461033c578560010161033e565b855b9050600061034b83610530565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e084018290526101008085018290528551808603909101815261012090940190945282519282019290922060018086018955600089815292909220909401849055865494955090939192916103f09190610723565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516104249392919061073a565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff166002811115610461576104616107a6565b600184015490915063ffffffff680100000000000000008204811691166000836002811115610492576104926107a6565b1480156104a757506104a481836107bc565b42115b15610506576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f916104f3916107d4565b60405180910390a1506001949350505050565b506000949350505050565b600381015415610522576000610525565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561059c5761059c6107a6565b905060008160028111156105b2576105b26107a6565b146105c7576105c28260016107bc565b61013d565b509392505050565b600080602083850312156105e257600080fd5b823567ffffffffffffffff808211156105fa57600080fd5b818501915085601f83011261060e57600080fd5b81358181111561061d57600080fd5b86602082850101111561062f57600080fd5b60209290920196919550909350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b85815260018060a01b0385166020820152836040820152608060608201526000610698608083018486610641565b979650505050505050565b60018060a01b03851681528360208201526060604082015260006106cb606083018486610641565b9695505050505050565b600080604083850312156106e857600080fd5b82356001600160a01b03811681146106ff57600080fd5b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156107355761073561070d565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561077c57858101830151858201608001528201610760565b8181111561078e576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156107cf576107cf61070d565b500190565b60208101600383106107f657634e487b7160e01b600052602160045260246000fd5b9190529056fea26469706673582212206b62acb6c77dbe7d4d69c04d66b5b6af207e0e940b9d6945a047852bcb79224a64736f6c634300080d0033", - "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/deployments/localhost/FeeManagerFacet.json b/deployments/localhost/FeeManagerFacet.json deleted file mode 100644 index 9965eb8..0000000 --- a/deployments/localhost/FeeManagerFacet.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "address": "0x81823BDB8ae08E546AD1eCcDa910Ab32B7253343", - "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": "0xb50df33fc68c4e3026f58b05ec12af9a214c7b0782681e18d730ca4e51202db5", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "627903", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe71dd9eebb6e72c2f31a7a3f41ca120d6797d13984df263d77d792b4e2efac67", - "transactionHash": "0xb50df33fc68c4e3026f58b05ec12af9a214c7b0782681e18d730ca4e51202db5", - "logs": [], - "blockNumber": 22, - "cumulativeGasUsed": "627903", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n address _validator\\n ) public view override returns (uint256) {\\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(\\n address _validator\\n ) public view override returns (uint256) {\\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\":\"0x9a0700b4e8c719870f7c20b53170ece646a2176f9a742caa1252e01a2d1cfa4f\",\"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(\\n address _validator\\n ) external view 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(\\n address _validator\\n ) external view 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\":\"0xed25b1867fdd7682ae01c4b833bec155596f1463abfea7728496b63e5f793753\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610a61806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80636e964cea1461005c5780637a5bf67c1461009b578063a859b983146100b0578063de7a8d11146100d1578063e8f56171146100e4575b600080fd5b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75546040516001600160a01b0390911681526020015b60405180910390f35b6100ae6100a93660046108ea565b6100f7565b005b6100c36100be366004610903565b61011d565b604051908152602001610092565b6100ae6100df366004610903565b61013f565b6100c36100f2366004610903565b610210565b600080516020610a0c83398151915261010f8161022b565b6101198183610287565b5050565b6000600080516020610a0c8339815191526101388184610418565b9392505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7554600080516020610a0c83398151915290600160a01b900460ff16156101c65760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff60a01b1916600160a01b17905560006101f2600080516020610a0c83398151915290565b90506101fe81846104ac565b50600201805460ff60a01b1916905550565b6000600080516020610a0c83398151915261013881846105fc565b80546001600160a01b031633146102845760405162461bcd60e51b815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060448201526064016101bd565b50565b6000805160206109ec83398151915260005b81600201548110156103d85760008260010182815481106102bc576102bc61092c565b6000918252602090912001546001600160a01b0316905080156103c55760006102e586836105fc565b905080156103c35760038601546102fd9084836106b6565b600387015560018601546000906103149083610958565b600288015460405163bec3fa1760e01b81526001600160a01b0386811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b5050604080516001600160a01b0387168152602081018690527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505b505b50806103d081610977565b915050610299565b50600183018290556040518281527fd454bae44ce74e91cf62780bdb9278052c00cfd79c13003d5761b400475b12f69060200160405180910390a1505050565b60006001600160a01b03821661046a5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006104858285610709565b905060006104a08287600301546107e890919063ffffffff16565b93505050505b92915050565b60006104b883836105fc565b9050600081116105025760405162461bcd60e51b81526020600482015260156024820152741b9bdd1a1a5b99c81d1bc81c995919595b481e595d605a1b60448201526064016101bd565b6000805160206109ec833981519152600061051d8285610709565b60038601549091506105309082856106b6565b600386015560018501546000906105479085610958565b600287015460405163bec3fa1760e01b81526001600160a01b0388811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561059957600080fd5b505af11580156105ad573d6000803e3d6000fd5b5050604080516001600160a01b0389168152602081018890527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505050505050565b60006001600160a01b03821661064e5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006106698285610709565b905060006106848284600301546107e890919063ffffffff16565b9050600061069f8388600301546107e890919063ffffffff16565b90506106ab8183610990565b979650505050505050565b6000600883106106d85760405162461bcd60e51b81526004016101bd906109a7565b60006106e485856107e8565b905060006106f284836109d3565b90506106ff868683610836565b9695505050505050565b60006001600160a01b03821661074d5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064016101bd565b60005b60018401548110156107a9578360010181815481106107715761077161092c565b6000918252602090912001546001600160a01b03908116908416036107975790506104a6565b806107a181610977565b915050610750565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b60448201526064016101bd565b60006008821061080a5760405162461bcd60e51b81526004016101bd906109a7565b600061081b60016340000000610990565b90508061082984601e610958565b85901c1691505092915050565b6000600883106108585760405162461bcd60e51b81526004016101bd906109a7565b61086760016340000000610990565b8211156108ac5760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b60448201526064016101bd565b60006108b984601e610958565b6108c860016340000000610990565b901b1990508481166108db85601e610958565b9390931b909217949350505050565b6000602082840312156108fc57600080fd5b5035919050565b60006020828403121561091557600080fd5b81356001600160a01b038116811461013857600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561097257610972610942565b500290565b60006001820161098957610989610942565b5060010190565b6000828210156109a2576109a2610942565b500390565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b600082198211156109e6576109e6610942565b50019056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73a264697066735822122042ec7a5adee122f0bcd4ccf2225d9453a458fd404b1a13df4cbd8b36b870d84e64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c80636e964cea1461005c5780637a5bf67c1461009b578063a859b983146100b0578063de7a8d11146100d1578063e8f56171146100e4575b600080fd5b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75546040516001600160a01b0390911681526020015b60405180910390f35b6100ae6100a93660046108ea565b6100f7565b005b6100c36100be366004610903565b61011d565b604051908152602001610092565b6100ae6100df366004610903565b61013f565b6100c36100f2366004610903565b610210565b600080516020610a0c83398151915261010f8161022b565b6101198183610287565b5050565b6000600080516020610a0c8339815191526101388184610418565b9392505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7554600080516020610a0c83398151915290600160a01b900460ff16156101c65760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff60a01b1916600160a01b17905560006101f2600080516020610a0c83398151915290565b90506101fe81846104ac565b50600201805460ff60a01b1916905550565b6000600080516020610a0c83398151915261013881846105fc565b80546001600160a01b031633146102845760405162461bcd60e51b815260206004820152601760248201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060448201526064016101bd565b50565b6000805160206109ec83398151915260005b81600201548110156103d85760008260010182815481106102bc576102bc61092c565b6000918252602090912001546001600160a01b0316905080156103c55760006102e586836105fc565b905080156103c35760038601546102fd9084836106b6565b600387015560018601546000906103149083610958565b600288015460405163bec3fa1760e01b81526001600160a01b0386811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b5050604080516001600160a01b0387168152602081018690527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505b505b50806103d081610977565b915050610299565b50600183018290556040518281527fd454bae44ce74e91cf62780bdb9278052c00cfd79c13003d5761b400475b12f69060200160405180910390a1505050565b60006001600160a01b03821661046a5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006104858285610709565b905060006104a08287600301546107e890919063ffffffff16565b93505050505b92915050565b60006104b883836105fc565b9050600081116105025760405162461bcd60e51b81526020600482015260156024820152741b9bdd1a1a5b99c81d1bc81c995919595b481e595d605a1b60448201526064016101bd565b6000805160206109ec833981519152600061051d8285610709565b60038601549091506105309082856106b6565b600386015560018501546000906105479085610958565b600287015460405163bec3fa1760e01b81526001600160a01b0388811660048301526024820184905292935091169063bec3fa1790604401600060405180830381600087803b15801561059957600080fd5b505af11580156105ad573d6000803e3d6000fd5b5050604080516001600160a01b0389168152602081018890527f0544e8b0e3ef3679366e27df87030668812cb3284d1acccfb1eb8a0e7b26ead3935001905060405180910390a1505050505050565b60006001600160a01b03821661064e5760405162461bcd60e51b81526020600482015260176024820152760616464726573732073686f756c64206e6f74206265203604c1b60448201526064016101bd565b6000805160206109ec83398151915260006106698285610709565b905060006106848284600301546107e890919063ffffffff16565b9050600061069f8388600301546107e890919063ffffffff16565b90506106ab8183610990565b979650505050505050565b6000600883106106d85760405162461bcd60e51b81526004016101bd906109a7565b60006106e485856107e8565b905060006106f284836109d3565b90506106ff868683610836565b9695505050505050565b60006001600160a01b03821661074d5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064016101bd565b60005b60018401548110156107a9578360010181815481106107715761077161092c565b6000918252602090912001546001600160a01b03908116908416036107975790506104a6565b806107a181610977565b915050610750565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b60448201526064016101bd565b60006008821061080a5760405162461bcd60e51b81526004016101bd906109a7565b600061081b60016340000000610990565b90508061082984601e610958565b85901c1691505092915050565b6000600883106108585760405162461bcd60e51b81526004016101bd906109a7565b61086760016340000000610990565b8211156108ac5760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b60448201526064016101bd565b60006108b984601e610958565b6108c860016340000000610990565b901b1990508481166108db85601e610958565b9390931b909217949350505050565b6000602082840312156108fc57600080fd5b5035919050565b60006020828403121561091557600080fd5b81356001600160a01b038116811461013857600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561097257610972610942565b500290565b60006001820161098957610989610942565b5060010190565b6000828210156109a2576109a2610942565b500390565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b600082198211156109e6576109e6610942565b50019056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fc844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73a264697066735822122042ec7a5adee122f0bcd4ccf2225d9453a458fd404b1a13df4cbd8b36b870d84e64736f6c634300080d0033", - "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/deployments/localhost/History.json b/deployments/localhost/History.json new file mode 100644 index 0000000..dc213aa --- /dev/null +++ b/deployments/localhost/History.json @@ -0,0 +1,381 @@ +{ + "address": "0xDe1ae319adBe59aeE53194f033B53adAfB9d3d8C", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "epochHash", + "type": "bytes32" + }, + { + "internalType": "uint128", + "name": "firstIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "lastIndex", + "type": "uint128" + } + ], + "indexed": false, + "internalType": "struct History.Claim", + "name": "claim", + "type": "tuple" + } + ], + "name": "NewClaimToHistory", + "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" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dapp", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_proofContext", + "type": "bytes" + } + ], + "name": "getClaim", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_consensus", + "type": "address" + } + ], + "name": "migrateToConsensus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_claimData", + "type": "bytes" + } + ], + "name": "submitClaim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x8eb88bdf96914178c6799eb5882e2808b1b039ac4d91b54940fdb8e4517014fd", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "494722", + "logsBloom": "0x00100000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001010000000000000000000400000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000001000000000000000000000000000000001000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000008000000", + "blockHash": "0xb869e790991e5724965062b9746f1d5b7aa9d76d6ba2ebe64e7bba125e7f9eb3", + "transactionHash": "0x8eb88bdf96914178c6799eb5882e2808b1b039ac4d91b54940fdb8e4517014fd", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 20, + "transactionHash": "0x8eb88bdf96914178c6799eb5882e2808b1b039ac4d91b54940fdb8e4517014fd", + "address": "0xDe1ae319adBe59aeE53194f033B53adAfB9d3d8C", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xb869e790991e5724965062b9746f1d5b7aa9d76d6ba2ebe64e7bba125e7f9eb3" + }, + { + "transactionIndex": 0, + "blockNumber": 20, + "transactionHash": "0x8eb88bdf96914178c6799eb5882e2808b1b039ac4d91b54940fdb8e4517014fd", + "address": "0xDe1ae319adBe59aeE53194f033B53adAfB9d3d8C", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "0x0000000000000000000000001b282530a52f67ce4613fe52d90273f960910afc" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xb869e790991e5724965062b9746f1d5b7aa9d76d6ba2ebe64e7bba125e7f9eb3" + } + ], + "blockNumber": 20, + "cumulativeGasUsed": "494722", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1B282530a52F67ce4613Fe52D90273f960910afc" + ], + "numDeployments": 1, + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"epochHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"firstIndex\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"lastIndex\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"struct History.Claim\",\"name\":\"claim\",\"type\":\"tuple\"}],\"name\":\"NewClaimToHistory\",\"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\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_proofContext\",\"type\":\"bytes\"}],\"name\":\"getClaim\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_consensus\",\"type\":\"address\"}],\"name\":\"migrateToConsensus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_claimData\",\"type\":\"bytes\"}],\"name\":\"submitClaim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract inherits OpenZeppelin's `Ownable` contract. For more information on `Ownable`, please consult OpenZeppelin's official documentation.\",\"events\":{\"NewClaimToHistory(address,(bytes32,uint128,uint128))\":{\"details\":\"MUST be triggered on a successful call to `submitClaim`.\",\"params\":{\"claim\":\"The newly-submitted claim\",\"dapp\":\"The address of the DApp\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"The initial owner\"}},\"getClaim(address,bytes)\":{\"params\":{\"_dapp\":\"The DApp address\",\"_proofContext\":\"Data for retrieving the desired claim\"},\"returns\":{\"_0\":\"The claimed epoch hash\",\"_1\":\"The index of the first input of the epoch in the input box\",\"_2\":\"The index of the last input of the epoch in the input box\"}},\"migrateToConsensus(address)\":{\"details\":\"Emits an `OwnershipTransferred` event. Should have access control.\",\"params\":{\"_consensus\":\"The new consensus\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"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.\"},\"submitClaim(bytes)\":{\"details\":\"Emits a `NewClaimToHistory` event. Should have access control.\",\"params\":{\"_claimData\":\"Data for submitting a claim\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"claims\":{\"details\":\"See the `getClaim` and `submitClaim` functions.\"}},\"title\":\"Simple History\",\"version\":1},\"userdoc\":{\"events\":{\"NewClaimToHistory(address,(bytes32,uint128,uint128))\":{\"notice\":\"A new claim regarding a specific DApp was submitted.\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Creates a `History` contract.\"},\"getClaim(address,bytes)\":{\"notice\":\"Get a specific claim regarding a specific DApp. There are several requirements for this function to be called successfully. * `_proofContext` MUST be well-encoded. In Solidity, it can be constructed as `abi.encode(claimIndex)`, where `claimIndex` is the claim index (type `uint256`). * `claimIndex` MUST be inside the interval `[0, n)` where `n` is the number of claims that have been submitted to `_dapp` already.\"},\"migrateToConsensus(address)\":{\"notice\":\"Transfer ownership to another consensus.\"},\"submitClaim(bytes)\":{\"notice\":\"Submit a claim regarding a DApp. There are several requirements for this function to be called successfully. * `_claimData` MUST be well-encoded. In Solidity, it can be constructed as `abi.encode(dapp, claim)`, where `dapp` is the DApp address (type `address`) and `claim` is the claim structure (type `Claim`). * `firstIndex` MUST be less than or equal to `lastIndex`. As a result, every claim MUST encompass AT LEAST one input. * If this is the DApp's first claim, then `firstIndex` MUST be `0`. Otherwise, `firstIndex` MUST be the `lastClaim.lastIndex + 1`. In other words, claims MUST NOT skip inputs.\"}},\"notice\":\"This contract stores claims for each DApp individually. This means that, for each DApp, the contract stores an array of `Claim` entries, where each `Claim` is composed of: * An epoch hash (`bytes32`) * A closed interval of input indices (`uint128`, `uint128`) The contract guarantees that the first interval starts at index 0, and that the following intervals don't have gaps or overlaps. Furthermore, claims can only be submitted by the contract owner through `submitClaim`, but can be retrieved by anyone with `getClaim`.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/history/History.sol\":\"History\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/history/History.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport {IHistory} from \\\"./IHistory.sol\\\";\\n\\n/// @title Simple History\\n///\\n/// @notice This contract stores claims for each DApp individually.\\n/// This means that, for each DApp, the contract stores an array of\\n/// `Claim` entries, where each `Claim` is composed of:\\n///\\n/// * An epoch hash (`bytes32`)\\n/// * A closed interval of input indices (`uint128`, `uint128`)\\n///\\n/// The contract guarantees that the first interval starts at index 0,\\n/// and that the following intervals don't have gaps or overlaps.\\n///\\n/// Furthermore, claims can only be submitted by the contract owner\\n/// through `submitClaim`, but can be retrieved by anyone with `getClaim`.\\n///\\n/// @dev This contract inherits OpenZeppelin's `Ownable` contract.\\n/// For more information on `Ownable`, please consult OpenZeppelin's official documentation.\\ncontract History is IHistory, Ownable {\\n struct Claim {\\n bytes32 epochHash;\\n uint128 firstIndex;\\n uint128 lastIndex;\\n }\\n\\n /// @notice Mapping from DApp address to array of claims.\\n /// @dev See the `getClaim` and `submitClaim` functions.\\n mapping(address => Claim[]) internal claims;\\n\\n /// @notice A new claim regarding a specific DApp was submitted.\\n /// @param dapp The address of the DApp\\n /// @param claim The newly-submitted claim\\n /// @dev MUST be triggered on a successful call to `submitClaim`.\\n event NewClaimToHistory(address indexed dapp, Claim claim);\\n\\n /// @notice Creates a `History` contract.\\n /// @param _owner The initial owner\\n constructor(address _owner) {\\n // constructor in Ownable already called `transferOwnership(msg.sender)`, so\\n // we only need to call `transferOwnership(_owner)` if _owner != msg.sender\\n if (_owner != msg.sender) {\\n transferOwnership(_owner);\\n }\\n }\\n\\n /// @notice Submit a claim regarding a DApp.\\n /// There are several requirements for this function to be called successfully.\\n ///\\n /// * `_claimData` MUST be well-encoded. In Solidity, it can be constructed\\n /// as `abi.encode(dapp, claim)`, where `dapp` is the DApp address (type `address`)\\n /// and `claim` is the claim structure (type `Claim`).\\n ///\\n /// * `firstIndex` MUST be less than or equal to `lastIndex`.\\n /// As a result, every claim MUST encompass AT LEAST one input.\\n ///\\n /// * If this is the DApp's first claim, then `firstIndex` MUST be `0`.\\n /// Otherwise, `firstIndex` MUST be the `lastClaim.lastIndex + 1`.\\n /// In other words, claims MUST NOT skip inputs.\\n ///\\n /// @inheritdoc IHistory\\n /// @dev Emits a `NewClaimToHistory` event. Should have access control.\\n function submitClaim(\\n bytes calldata _claimData\\n ) external override onlyOwner {\\n (address dapp, Claim memory claim) = abi.decode(\\n _claimData,\\n (address, Claim)\\n );\\n\\n require(claim.firstIndex <= claim.lastIndex, \\\"History: FI > LI\\\");\\n\\n Claim[] storage dappClaims = claims[dapp];\\n uint256 numDAppClaims = dappClaims.length;\\n\\n require(\\n claim.firstIndex ==\\n (\\n (numDAppClaims == 0)\\n ? 0\\n : (dappClaims[numDAppClaims - 1].lastIndex + 1)\\n ),\\n \\\"History: unclaimed inputs\\\"\\n );\\n\\n dappClaims.push(claim);\\n\\n emit NewClaimToHistory(dapp, claim);\\n }\\n\\n /// @notice Get a specific claim regarding a specific DApp.\\n /// There are several requirements for this function to be called successfully.\\n ///\\n /// * `_proofContext` MUST be well-encoded. In Solidity, it can be constructed\\n /// as `abi.encode(claimIndex)`, where `claimIndex` is the claim index (type `uint256`).\\n ///\\n /// * `claimIndex` MUST be inside the interval `[0, n)` where `n` is the number of claims\\n /// that have been submitted to `_dapp` already.\\n ///\\n /// @inheritdoc IHistory\\n function getClaim(\\n address _dapp,\\n bytes calldata _proofContext\\n ) external view override returns (bytes32, uint256, uint256) {\\n uint256 claimIndex = abi.decode(_proofContext, (uint256));\\n\\n Claim memory claim = claims[_dapp][claimIndex];\\n\\n return (claim.epochHash, claim.firstIndex, claim.lastIndex);\\n }\\n\\n /// @inheritdoc IHistory\\n /// @dev Emits an `OwnershipTransferred` event. Should have access control.\\n function migrateToConsensus(\\n address _consensus\\n ) external override onlyOwner {\\n transferOwnership(_consensus);\\n }\\n}\\n\",\"keccak256\":\"0x607253a9e73d3fe0b98e2c5d7b6f9ee1dad48d7cf4a1284b4f1361d74178da7a\",\"license\":\"Apache-2.0\"},\"contracts/history/IHistory.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title History interface\\ninterface IHistory {\\n // Permissioned functions\\n\\n /// @notice Submit a claim.\\n /// The encoding of `_claimData` might vary\\n /// depending on the history implementation.\\n /// @param _claimData Data for submitting a claim\\n /// @dev Should have access control.\\n function submitClaim(bytes calldata _claimData) external;\\n\\n /// @notice Transfer ownership to another consensus.\\n /// @param _consensus The new consensus\\n /// @dev Should have access control.\\n function migrateToConsensus(address _consensus) external;\\n\\n // Permissionless functions\\n\\n /// @notice Get a specific claim regarding a specific DApp.\\n /// The encoding of `_proofContext` might vary\\n /// depending on the history implementation.\\n /// @param _dapp The DApp address\\n /// @param _proofContext Data for retrieving the desired claim\\n /// @return epochHash_ The claimed epoch hash\\n /// @return firstInputIndex_ The index of the first input of the epoch in the input box\\n /// @return lastInputIndex_ The index of the last input of the epoch in the input box\\n function getClaim(\\n address _dapp,\\n bytes calldata _proofContext\\n )\\n external\\n view\\n returns (\\n bytes32 epochHash_,\\n uint256 firstInputIndex_,\\n uint256 lastInputIndex_\\n );\\n}\\n\",\"keccak256\":\"0xfe0404f078a3a6f761beea8afbb2fac322fd2900f7ad2e2b866504c7aa54568f\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f91610181565b61003833610057565b6001600160a01b038116331461005157610051816100a7565b506101b1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6100af610125565b6001600160a01b0381166101195760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61012281610057565b50565b6000546001600160a01b0316331461017f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610110565b565b60006020828403121561019357600080fd5b81516001600160a01b03811681146101aa57600080fd5b9392505050565b61075f806101c06000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063715018a6146100675780638da5cb5b14610071578063d79a824014610091578063ddfdfbb0146100bf578063f2fde38b146100d2578063fc411683146100e5575b600080fd5b61006f6100f8565b005b6000546040516001600160a01b0390911681526020015b60405180910390f35b6100a461009f36600461052f565b61010c565b60408051938452602084019290925290820152606001610088565b61006f6100cd366004610584565b6101a5565b61006f6100e03660046105c6565b61039d565b61006f6100f33660046105c6565b610416565b610100610427565b61010a6000610481565b565b600080808061011d858701876105ea565b6001600160a01b0388166000908152600160205260408120805492935090918390811061014c5761014c610603565b60009182526020918290206040805160608101825260029390930290910180548084526001909101546001600160801b03808216958501869052600160801b90910416929091018290529a919950975095505050505050565b6101ad610427565b6000806101bc83850185610635565b9150915080604001516001600160801b031681602001516001600160801b031611156102225760405162461bcd60e51b815260206004820152601060248201526f486973746f72793a204649203e204c4960801b60448201526064015b60405180910390fd5b6001600160a01b038216600090815260016020526040902080548015610294578161024e6001836106e9565b8154811061025e5761025e610603565b906000526020600020906002020160010160109054906101000a90046001600160801b0316600161028f9190610702565b610297565b60005b6001600160801b031683602001516001600160801b0316146102fb5760405162461bcd60e51b815260206004820152601960248201527f486973746f72793a20756e636c61696d656420696e70757473000000000000006044820152606401610219565b8154600180820184556000848152602090819020865160029094020183815586820180516040808a0180516001600160801b03938416600160801b9185169190910217949096019390935582519586529051811692850192909252915116908201526001600160a01b038516907fb71880d7a0c514d48c0296b2721b0a4f9641a45117960f2ca86b5b7873c4ab2f9060600160405180910390a2505050505050565b6103a5610427565b6001600160a01b03811661040a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610219565b61041381610481565b50565b61041e610427565b6104138161039d565b6000546001600160a01b0316331461010a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610219565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461041357600080fd5b60008083601f8401126104f857600080fd5b50813567ffffffffffffffff81111561051057600080fd5b60208301915083602082850101111561052857600080fd5b9250929050565b60008060006040848603121561054457600080fd5b833561054f816104d1565b9250602084013567ffffffffffffffff81111561056b57600080fd5b610577868287016104e6565b9497909650939450505050565b6000806020838503121561059757600080fd5b823567ffffffffffffffff8111156105ae57600080fd5b6105ba858286016104e6565b90969095509350505050565b6000602082840312156105d857600080fd5b81356105e3816104d1565b9392505050565b6000602082840312156105fc57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160801b038116811461063057600080fd5b919050565b600080828403608081121561064957600080fd5b8335610654816104d1565b92506060601f198201121561066857600080fd5b506040516060810181811067ffffffffffffffff8211171561069a57634e487b7160e01b600052604160045260246000fd5b8060405250602084013581526106b260408501610619565b60208201526106c360608501610619565b6040820152809150509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106fc576106fc6106d3565b92915050565b6001600160801b03818116838216019080821115610722576107226106d3565b509291505056fea26469706673582212201fc5dfb9d50cb3efefe40c7ced59b7b296f6d072ed8005ef3de36946cd77e28364736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c8063715018a6146100675780638da5cb5b14610071578063d79a824014610091578063ddfdfbb0146100bf578063f2fde38b146100d2578063fc411683146100e5575b600080fd5b61006f6100f8565b005b6000546040516001600160a01b0390911681526020015b60405180910390f35b6100a461009f36600461052f565b61010c565b60408051938452602084019290925290820152606001610088565b61006f6100cd366004610584565b6101a5565b61006f6100e03660046105c6565b61039d565b61006f6100f33660046105c6565b610416565b610100610427565b61010a6000610481565b565b600080808061011d858701876105ea565b6001600160a01b0388166000908152600160205260408120805492935090918390811061014c5761014c610603565b60009182526020918290206040805160608101825260029390930290910180548084526001909101546001600160801b03808216958501869052600160801b90910416929091018290529a919950975095505050505050565b6101ad610427565b6000806101bc83850185610635565b9150915080604001516001600160801b031681602001516001600160801b031611156102225760405162461bcd60e51b815260206004820152601060248201526f486973746f72793a204649203e204c4960801b60448201526064015b60405180910390fd5b6001600160a01b038216600090815260016020526040902080548015610294578161024e6001836106e9565b8154811061025e5761025e610603565b906000526020600020906002020160010160109054906101000a90046001600160801b0316600161028f9190610702565b610297565b60005b6001600160801b031683602001516001600160801b0316146102fb5760405162461bcd60e51b815260206004820152601960248201527f486973746f72793a20756e636c61696d656420696e70757473000000000000006044820152606401610219565b8154600180820184556000848152602090819020865160029094020183815586820180516040808a0180516001600160801b03938416600160801b9185169190910217949096019390935582519586529051811692850192909252915116908201526001600160a01b038516907fb71880d7a0c514d48c0296b2721b0a4f9641a45117960f2ca86b5b7873c4ab2f9060600160405180910390a2505050505050565b6103a5610427565b6001600160a01b03811661040a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610219565b61041381610481565b50565b61041e610427565b6104138161039d565b6000546001600160a01b0316331461010a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610219565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461041357600080fd5b60008083601f8401126104f857600080fd5b50813567ffffffffffffffff81111561051057600080fd5b60208301915083602082850101111561052857600080fd5b9250929050565b60008060006040848603121561054457600080fd5b833561054f816104d1565b9250602084013567ffffffffffffffff81111561056b57600080fd5b610577868287016104e6565b9497909650939450505050565b6000806020838503121561059757600080fd5b823567ffffffffffffffff8111156105ae57600080fd5b6105ba858286016104e6565b90969095509350505050565b6000602082840312156105d857600080fd5b81356105e3816104d1565b9392505050565b6000602082840312156105fc57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160801b038116811461063057600080fd5b919050565b600080828403608081121561064957600080fd5b8335610654816104d1565b92506060601f198201121561066857600080fd5b506040516060810181811067ffffffffffffffff8211171561069a57634e487b7160e01b600052604160045260246000fd5b8060405250602084013581526106b260408501610619565b60208201526106c360608501610619565b6040820152809150509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106fc576106fc6106d3565b92915050565b6001600160801b03818116838216019080821115610722576107226106d3565b509291505056fea26469706673582212201fc5dfb9d50cb3efefe40c7ced59b7b296f6d072ed8005ef3de36946cd77e28364736f6c63430008130033", + "devdoc": { + "details": "This contract inherits OpenZeppelin's `Ownable` contract. For more information on `Ownable`, please consult OpenZeppelin's official documentation.", + "events": { + "NewClaimToHistory(address,(bytes32,uint128,uint128))": { + "details": "MUST be triggered on a successful call to `submitClaim`.", + "params": { + "claim": "The newly-submitted claim", + "dapp": "The address of the DApp" + } + } + }, + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_owner": "The initial owner" + } + }, + "getClaim(address,bytes)": { + "params": { + "_dapp": "The DApp address", + "_proofContext": "Data for retrieving the desired claim" + }, + "returns": { + "_0": "The claimed epoch hash", + "_1": "The index of the first input of the epoch in the input box", + "_2": "The index of the last input of the epoch in the input box" + } + }, + "migrateToConsensus(address)": { + "details": "Emits an `OwnershipTransferred` event. Should have access control.", + "params": { + "_consensus": "The new consensus" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "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." + }, + "submitClaim(bytes)": { + "details": "Emits a `NewClaimToHistory` event. Should have access control.", + "params": { + "_claimData": "Data for submitting a claim" + } + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "stateVariables": { + "claims": { + "details": "See the `getClaim` and `submitClaim` functions." + } + }, + "title": "Simple History", + "version": 1 + }, + "userdoc": { + "events": { + "NewClaimToHistory(address,(bytes32,uint128,uint128))": { + "notice": "A new claim regarding a specific DApp was submitted." + } + }, + "kind": "user", + "methods": { + "constructor": { + "notice": "Creates a `History` contract." + }, + "getClaim(address,bytes)": { + "notice": "Get a specific claim regarding a specific DApp. There are several requirements for this function to be called successfully. * `_proofContext` MUST be well-encoded. In Solidity, it can be constructed as `abi.encode(claimIndex)`, where `claimIndex` is the claim index (type `uint256`). * `claimIndex` MUST be inside the interval `[0, n)` where `n` is the number of claims that have been submitted to `_dapp` already." + }, + "migrateToConsensus(address)": { + "notice": "Transfer ownership to another consensus." + }, + "submitClaim(bytes)": { + "notice": "Submit a claim regarding a DApp. There are several requirements for this function to be called successfully. * `_claimData` MUST be well-encoded. In Solidity, it can be constructed as `abi.encode(dapp, claim)`, where `dapp` is the DApp address (type `address`) and `claim` is the claim structure (type `Claim`). * `firstIndex` MUST be less than or equal to `lastIndex`. As a result, every claim MUST encompass AT LEAST one input. * If this is the DApp's first claim, then `firstIndex` MUST be `0`. Otherwise, `firstIndex` MUST be the `lastClaim.lastIndex + 1`. In other words, claims MUST NOT skip inputs." + } + }, + "notice": "This contract stores claims for each DApp individually. This means that, for each DApp, the contract stores an array of `Claim` entries, where each `Claim` is composed of: * An epoch hash (`bytes32`) * A closed interval of input indices (`uint128`, `uint128`) The contract guarantees that the first interval starts at index 0, and that the following intervals don't have gaps or overlaps. Furthermore, claims can only be submitted by the contract owner through `submitClaim`, but can be retrieved by anyone with `getClaim`.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1155, + "contract": "contracts/history/History.sol:History", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3072, + "contract": "contracts/history/History.sol:History", + "label": "claims", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_array(t_struct(Claim)3065_storage)dyn_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Claim)3065_storage)dyn_storage": { + "base": "t_struct(Claim)3065_storage", + "encoding": "dynamic_array", + "label": "struct History.Claim[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_array(t_struct(Claim)3065_storage)dyn_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct History.Claim[])", + "numberOfBytes": "32", + "value": "t_array(t_struct(Claim)3065_storage)dyn_storage" + }, + "t_struct(Claim)3065_storage": { + "encoding": "inplace", + "label": "struct History.Claim", + "members": [ + { + "astId": 3060, + "contract": "contracts/history/History.sol:History", + "label": "epochHash", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 3062, + "contract": "contracts/history/History.sol:History", + "label": "firstIndex", + "offset": 0, + "slot": "1", + "type": "t_uint128" + }, + { + "astId": 3064, + "contract": "contracts/history/History.sol:History", + "label": "lastIndex", + "offset": 16, + "slot": "1", + "type": "t_uint128" + } + ], + "numberOfBytes": "64" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + } + } + } +} \ No newline at end of file diff --git a/deployments/localhost/InputBox.json b/deployments/localhost/InputBox.json new file mode 100644 index 0000000..7e0f76e --- /dev/null +++ b/deployments/localhost/InputBox.json @@ -0,0 +1,234 @@ +{ + "address": "0x5a723220579C0DCb8C9253E6b4c62e572E379945", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "dapp", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "inboxInputIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "name": "InputAdded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dapp", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_input", + "type": "bytes" + } + ], + "name": "addInput", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dapp", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getInputHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dapp", + "type": "address" + } + ], + "name": "getNumberOfInputs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xe8b53f8741c046d1f414b7f128a8e7b3379a37dc568080510451101ca42d7521", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "271870", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd75d29d835377e21bcd0122436e44656ca83ed3332349bca23114818fcd00c8c", + "transactionHash": "0xe8b53f8741c046d1f414b7f128a8e7b3379a37dc568080510451101ca42d7521", + "logs": [], + "blockNumber": 13, + "cumulativeGasUsed": "271870", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ccf852a6f03ad282136085842817ac99", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"inboxInputIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"InputAdded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_input\",\"type\":\"bytes\"}],\"name\":\"addInput\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getInputHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"}],\"name\":\"getNumberOfInputs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"InputAdded(address,uint256,address,bytes)\":{\"details\":\"MUST be triggered on a successful call to `addInput`.\",\"params\":{\"dapp\":\"The address of the DApp\",\"inboxInputIndex\":\"The index of the input in the input box\",\"input\":\"The contents of the input\",\"sender\":\"The address that sent the input\"}}},\"kind\":\"dev\",\"methods\":{\"addInput(address,bytes)\":{\"details\":\"MUST fire an `InputAdded` event accordingly.\",\"params\":{\"_dapp\":\"The address of the DApp\",\"_input\":\"The contents of the input\"},\"returns\":{\"_0\":\"The hash of the input plus some extra metadata\"}},\"getInputHash(address,uint256)\":{\"details\":\"`_index` MUST be in the interval `[0,n)` where `n` is the number of inputs in the DApp's input box. See the `getNumberOfInputs` function.\",\"params\":{\"_dapp\":\"The address of the DApp\",\"_index\":\"The index of the input in the DApp's input box\"},\"returns\":{\"_0\":\"The hash of the input at the provided index in the DApp's input box\"}},\"getNumberOfInputs(address)\":{\"params\":{\"_dapp\":\"The address of the DApp\"},\"returns\":{\"_0\":\"Number of inputs in the DApp's input box\"}}},\"stateVariables\":{\"inputBoxes\":{\"details\":\"See the `getNumberOfInputs`, `getInputHash` and `addInput` functions.\"}},\"title\":\"Input Box\",\"version\":1},\"userdoc\":{\"events\":{\"InputAdded(address,uint256,address,bytes)\":{\"notice\":\"Emitted when an input is added to a DApp's input box.\"}},\"kind\":\"user\",\"methods\":{\"addInput(address,bytes)\":{\"notice\":\"Add an input to a DApp's input box.\"},\"getInputHash(address,uint256)\":{\"notice\":\"Get the hash of an input in a DApp's input box.\"},\"getNumberOfInputs(address)\":{\"notice\":\"Get the number of inputs in a DApp's input box.\"}},\"notice\":\"Trustless and permissionless contract that receives arbitrary blobs (called \\\"inputs\\\") from anyone and adds a compound hash to an append-only list (called \\\"input box\\\"). Each DApp has its own input box. The hash that is stored on-chain is composed by the hash of the input blob, the block number and timestamp, the input sender address, and the input index. Data availability is guaranteed by the emission of `InputAdded` events on every successful call to `addInput`. This ensures that inputs can be retrieved by anyone at any time, without having to rely on centralized data providers. From the perspective of this contract, inputs are encoding-agnostic byte arrays. It is up to the DApp to interpret, validate and act upon inputs.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/inputs/InputBox.sol\":\"InputBox\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/common/CanonicalMachine.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Canonical Machine Constants Library\\n///\\n/// @notice Defines several constants related to the reference implementation\\n/// of the RISC-V machine that runs Linux, also known as the \\\"Cartesi Machine\\\".\\nlibrary CanonicalMachine {\\n /// @notice Base-2 logarithm of number of bytes.\\n type Log2Size is uint64;\\n\\n /// @notice Machine word size (8 bytes).\\n Log2Size constant WORD_LOG2_SIZE = Log2Size.wrap(3);\\n\\n /// @notice Machine address space size (2^64 bytes).\\n Log2Size constant MACHINE_LOG2_SIZE = Log2Size.wrap(64);\\n\\n /// @notice Keccak-256 output size (32 bytes).\\n Log2Size constant KECCAK_LOG2_SIZE = Log2Size.wrap(5);\\n\\n /// @notice Maximum input size (32 megabytes).\\n Log2Size constant INPUT_MAX_LOG2_SIZE = Log2Size.wrap(25);\\n\\n /// @notice Maximum voucher metadata memory range (2 megabytes).\\n Log2Size constant VOUCHER_METADATA_LOG2_SIZE = Log2Size.wrap(21);\\n\\n /// @notice Maximum notice metadata memory range (2 megabytes).\\n Log2Size constant NOTICE_METADATA_LOG2_SIZE = Log2Size.wrap(21);\\n\\n /// @notice Maximum epoch voucher memory range (128 megabytes).\\n Log2Size constant EPOCH_VOUCHER_LOG2_SIZE = Log2Size.wrap(37);\\n\\n /// @notice Maximum epoch notice memory range (128 megabytes).\\n Log2Size constant EPOCH_NOTICE_LOG2_SIZE = Log2Size.wrap(37);\\n\\n /// @notice Unwrap `s` into its underlying uint64 value.\\n /// @param s Base-2 logarithm of some number of bytes\\n function uint64OfSize(Log2Size s) internal pure returns (uint64) {\\n return Log2Size.unwrap(s);\\n }\\n\\n /// @notice Return the position of an 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 Base-2 logarithm of intra memory range size\\n function getIntraMemoryRangePosition(\\n uint64 index,\\n Log2Size log2Size\\n ) internal pure returns (uint64) {\\n return index << Log2Size.unwrap(log2Size);\\n }\\n}\\n\",\"keccak256\":\"0x54a77c72297ee124bb97c691b823dacb8ae427325db1cdeb9416c743accb636b\",\"license\":\"Apache-2.0\"},\"contracts/inputs/IInputBox.sol\":{\"content\":\"// Copyright 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.8;\\n\\n/// @title Input Box interface\\ninterface IInputBox {\\n /// @notice Emitted when an input is added to a DApp's input box.\\n /// @param dapp The address of the DApp\\n /// @param inboxInputIndex The index of the input in the input box\\n /// @param sender The address that sent the input\\n /// @param input The contents of the input\\n /// @dev MUST be triggered on a successful call to `addInput`.\\n event InputAdded(\\n address indexed dapp,\\n uint256 indexed inboxInputIndex,\\n address sender,\\n bytes input\\n );\\n\\n /// @notice Add an input to a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _input The contents of the input\\n /// @return The hash of the input plus some extra metadata\\n /// @dev MUST fire an `InputAdded` event accordingly.\\n function addInput(\\n address _dapp,\\n bytes calldata _input\\n ) external returns (bytes32);\\n\\n /// @notice Get the number of inputs in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @return Number of inputs in the DApp's input box\\n function getNumberOfInputs(address _dapp) external view returns (uint256);\\n\\n /// @notice Get the hash of an input in a DApp's input box.\\n /// @param _dapp The address of the DApp\\n /// @param _index The index of the input in the DApp's input box\\n /// @return The hash of the input at the provided index in the DApp's input box\\n /// @dev `_index` MUST be in the interval `[0,n)` where `n` is the number of\\n /// inputs in the DApp's input box. See the `getNumberOfInputs` function.\\n function getInputHash(\\n address _dapp,\\n uint256 _index\\n ) external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x2addd467a24cde2131784103080aeb28df40d87ba19c5fd92bf96c0c074603df\",\"license\":\"Apache-2.0\"},\"contracts/inputs/InputBox.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {IInputBox} from \\\"./IInputBox.sol\\\";\\nimport {LibInput} from \\\"../library/LibInput.sol\\\";\\n\\n/// @title Input Box\\n///\\n/// @notice Trustless and permissionless contract that receives arbitrary blobs\\n/// (called \\\"inputs\\\") from anyone and adds a compound hash to an append-only list\\n/// (called \\\"input box\\\"). Each DApp has its own input box.\\n///\\n/// The hash that is stored on-chain is composed by the hash of the input blob,\\n/// the block number and timestamp, the input sender address, and the input index.\\n///\\n/// Data availability is guaranteed by the emission of `InputAdded` events\\n/// on every successful call to `addInput`. This ensures that inputs can be\\n/// retrieved by anyone at any time, without having to rely on centralized data\\n/// providers.\\n///\\n/// From the perspective of this contract, inputs are encoding-agnostic byte\\n/// arrays. It is up to the DApp to interpret, validate and act upon inputs.\\ncontract InputBox is IInputBox {\\n /// @notice Mapping from DApp address to list of input hashes.\\n /// @dev See the `getNumberOfInputs`, `getInputHash` and `addInput` functions.\\n mapping(address => bytes32[]) internal inputBoxes;\\n\\n function addInput(\\n address _dapp,\\n bytes calldata _input\\n ) external override returns (bytes32) {\\n bytes32[] storage inputBox = inputBoxes[_dapp];\\n uint256 inboxInputIndex = inputBox.length;\\n\\n bytes32 inputHash = LibInput.computeInputHash(\\n msg.sender,\\n block.number,\\n block.timestamp,\\n _input,\\n inboxInputIndex\\n );\\n\\n // add input to correct inbox\\n inputBox.push(inputHash);\\n\\n // block.number and timestamp can be retrieved by the event metadata itself\\n emit InputAdded(_dapp, inboxInputIndex, msg.sender, _input);\\n\\n return inputHash;\\n }\\n\\n function getNumberOfInputs(\\n address _dapp\\n ) external view override returns (uint256) {\\n return inputBoxes[_dapp].length;\\n }\\n\\n function getInputHash(\\n address _dapp,\\n uint256 _index\\n ) external view override returns (bytes32) {\\n return inputBoxes[_dapp][_index];\\n }\\n}\\n\",\"keccak256\":\"0x6a941849c9adf09595a165f91abd42cd63e1b8532b1aeb0b2520811f217f2012\",\"license\":\"Apache-2.0\"},\"contracts/library/LibInput.sol\":{\"content\":\"// Copyright 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.8;\\n\\nimport {CanonicalMachine} from \\\"../common/CanonicalMachine.sol\\\";\\n\\n/// @title Input Library\\nlibrary LibInput {\\n using CanonicalMachine for CanonicalMachine.Log2Size;\\n\\n /// @notice Summarize input data in a single hash.\\n /// @param sender `msg.sender`\\n /// @param blockNumber `block.number`\\n /// @param blockTimestamp `block.timestamp`\\n /// @param input The input blob\\n /// @param inboxInputIndex The index of the input in the input box\\n /// @return The input hash\\n function computeInputHash(\\n address sender,\\n uint256 blockNumber,\\n uint256 blockTimestamp,\\n bytes calldata input,\\n uint256 inboxInputIndex\\n ) internal pure returns (bytes32) {\\n // Currently sending an input larger than driveSize surpasses the block gas limit\\n // But we keep the following check in case this changes in the future\\n require(\\n input.length <=\\n (1 << CanonicalMachine.INPUT_MAX_LOG2_SIZE.uint64OfSize()),\\n \\\"input len: [0,driveSize]\\\"\\n );\\n\\n bytes32 keccakMetadata = keccak256(\\n abi.encode(\\n sender,\\n blockNumber,\\n blockTimestamp,\\n 0, //TODO decide how to deal with epoch index\\n inboxInputIndex // input index in the input box\\n )\\n );\\n\\n bytes32 keccakInput = keccak256(input);\\n\\n return keccak256(abi.encode(keccakMetadata, keccakInput));\\n }\\n}\\n\",\"keccak256\":\"0x3f16a030cc24e730f2a4fa30135a39e4ead7217c81e7e772a6263b0ba9408511\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506103f2806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631789cd631461004657806361a93c871461006b578063677087c914610094575b600080fd5b610059610054366004610287565b6100a7565b60405190815260200160405180910390f35b61005961007936600461030a565b6001600160a01b031660009081526020819052604090205490565b6100596100a236600461032c565b61013b565b6001600160a01b03831660009081526020819052604081208054826100d0334342898987610178565b83546001810185556000858152602090200181905560405190915082906001600160a01b038916907f6aaa400068bf4ca337265e2a1e1e841f66b8597fd5b452fdc52a44bed28a0784906101299033908b908b90610356565b60405180910390a39695505050505050565b6001600160a01b038216600090815260208190526040812080548390811061016557610165610396565b9060005260206000200154905092915050565b600063020000008311156101d25760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640160405180910390fd5b604080516001600160a01b03891660208201529081018790526060810186905260006080820181905260a082018490529060c001604051602081830303815290604052805190602001209050600085856040516102309291906103ac565b604080519182900382206020808401959095528282015280518083038201815260609092019052805192019190912098975050505050505050565b80356001600160a01b038116811461028257600080fd5b919050565b60008060006040848603121561029c57600080fd5b6102a58461026b565b9250602084013567ffffffffffffffff808211156102c257600080fd5b818601915086601f8301126102d657600080fd5b8135818111156102e557600080fd5b8760208285010111156102f757600080fd5b6020830194508093505050509250925092565b60006020828403121561031c57600080fd5b6103258261026b565b9392505050565b6000806040838503121561033f57600080fd5b6103488361026b565b946020939093013593505050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b634e487b7160e01b600052603260045260246000fd5b818382376000910190815291905056fea2646970667358221220fd50acf7a83485b79e97d1cd8af8cb872bd7a16cc845951161e92fbbb7252fbb64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80631789cd631461004657806361a93c871461006b578063677087c914610094575b600080fd5b610059610054366004610287565b6100a7565b60405190815260200160405180910390f35b61005961007936600461030a565b6001600160a01b031660009081526020819052604090205490565b6100596100a236600461032c565b61013b565b6001600160a01b03831660009081526020819052604081208054826100d0334342898987610178565b83546001810185556000858152602090200181905560405190915082906001600160a01b038916907f6aaa400068bf4ca337265e2a1e1e841f66b8597fd5b452fdc52a44bed28a0784906101299033908b908b90610356565b60405180910390a39695505050505050565b6001600160a01b038216600090815260208190526040812080548390811061016557610165610396565b9060005260206000200154905092915050565b600063020000008311156101d25760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640160405180910390fd5b604080516001600160a01b03891660208201529081018790526060810186905260006080820181905260a082018490529060c001604051602081830303815290604052805190602001209050600085856040516102309291906103ac565b604080519182900382206020808401959095528282015280518083038201815260609092019052805192019190912098975050505050505050565b80356001600160a01b038116811461028257600080fd5b919050565b60008060006040848603121561029c57600080fd5b6102a58461026b565b9250602084013567ffffffffffffffff808211156102c257600080fd5b818601915086601f8301126102d657600080fd5b8135818111156102e557600080fd5b8760208285010111156102f757600080fd5b6020830194508093505050509250925092565b60006020828403121561031c57600080fd5b6103258261026b565b9392505050565b6000806040838503121561033f57600080fd5b6103488361026b565b946020939093013593505050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b634e487b7160e01b600052603260045260246000fd5b818382376000910190815291905056fea2646970667358221220fd50acf7a83485b79e97d1cd8af8cb872bd7a16cc845951161e92fbbb7252fbb64736f6c63430008130033", + "devdoc": { + "events": { + "InputAdded(address,uint256,address,bytes)": { + "details": "MUST be triggered on a successful call to `addInput`.", + "params": { + "dapp": "The address of the DApp", + "inboxInputIndex": "The index of the input in the input box", + "input": "The contents of the input", + "sender": "The address that sent the input" + } + } + }, + "kind": "dev", + "methods": { + "addInput(address,bytes)": { + "details": "MUST fire an `InputAdded` event accordingly.", + "params": { + "_dapp": "The address of the DApp", + "_input": "The contents of the input" + }, + "returns": { + "_0": "The hash of the input plus some extra metadata" + } + }, + "getInputHash(address,uint256)": { + "details": "`_index` MUST be in the interval `[0,n)` where `n` is the number of inputs in the DApp's input box. See the `getNumberOfInputs` function.", + "params": { + "_dapp": "The address of the DApp", + "_index": "The index of the input in the DApp's input box" + }, + "returns": { + "_0": "The hash of the input at the provided index in the DApp's input box" + } + }, + "getNumberOfInputs(address)": { + "params": { + "_dapp": "The address of the DApp" + }, + "returns": { + "_0": "Number of inputs in the DApp's input box" + } + } + }, + "stateVariables": { + "inputBoxes": { + "details": "See the `getNumberOfInputs`, `getInputHash` and `addInput` functions." + } + }, + "title": "Input Box", + "version": 1 + }, + "userdoc": { + "events": { + "InputAdded(address,uint256,address,bytes)": { + "notice": "Emitted when an input is added to a DApp's input box." + } + }, + "kind": "user", + "methods": { + "addInput(address,bytes)": { + "notice": "Add an input to a DApp's input box." + }, + "getInputHash(address,uint256)": { + "notice": "Get the hash of an input in a DApp's input box." + }, + "getNumberOfInputs(address)": { + "notice": "Get the number of inputs in a DApp's input box." + } + }, + "notice": "Trustless and permissionless contract that receives arbitrary blobs (called \"inputs\") from anyone and adds a compound hash to an append-only list (called \"input box\"). Each DApp has its own input box. The hash that is stored on-chain is composed by the hash of the input blob, the block number and timestamp, the input sender address, and the input index. Data availability is guaranteed by the emission of `InputAdded` events on every successful call to `addInput`. This ensures that inputs can be retrieved by anyone at any time, without having to rely on centralized data providers. From the perspective of this contract, inputs are encoding-agnostic byte arrays. It is up to the DApp to interpret, validate and act upon inputs.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3324, + "contract": "contracts/inputs/InputBox.sol:InputBox", + "label": "inputBoxes", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_array(t_bytes32)dyn_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_array(t_bytes32)dyn_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bytes32[])", + "numberOfBytes": "32", + "value": "t_array(t_bytes32)dyn_storage" + } + } + } +} \ No newline at end of file diff --git a/deployments/localhost/InputFacet.json b/deployments/localhost/InputFacet.json deleted file mode 100644 index 156914c..0000000 --- a/deployments/localhost/InputFacet.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "address": "0xeA8538B194742b992B19e694C13D63120908880e", - "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": "0x4d824e412c26f6160092179cf935d5a6d885ca0c0a180c71395d80d5c2900458", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "445554", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x91ec0490c71913f9bdaf39a1b3f7fa18e559a32080c1fa06a847af1e4a8c46c2", - "transactionHash": "0x4d824e412c26f6160092179cf935d5a6d885ca0c0a180c71395d80d5c2900458", - "logs": [], - "blockNumber": 23, - "cumulativeGasUsed": "445554", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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\":\"Indicates that an input was added to the accumulating epoch's inbox\"}},\"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 an input to the accumulating epoch's inbox\\n /// @param _input bytes array of input\\n /// @return hash of the input\\n /// @dev There is a maximum size for the input data that is defined by the DApp\\n function addInput(bytes calldata _input) external returns (bytes32);\\n\\n /// @notice Returns the hash of the input at the provided input index, for the current sealed epoch\\n /// @param _index position of the input on inbox\\n /// @return hash of the input\\n function getInput(uint256 _index) external view returns (bytes32);\\n\\n /// @notice Returns the number of inputs on the current sealed epoch's inbox\\n /// @return number of inputs of non active inbox\\n function getNumberOfInputs() external view returns (uint256);\\n\\n /// @notice Returns the internal index of the current accumulating inbox\\n /// @return index of current accumulating inbox\\n function getCurrentInbox() external view returns (uint256);\\n\\n /// @notice Indicates that an input was added to the accumulating epoch's inbox\\n /// @param epochNumber which epoch this input belongs to\\n /// @param inputIndex index of the input just added\\n /// @param sender msg.sender address\\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\":\"0x56006d5601a56b43d9274dd72c3f11915e8cfec9874dd9e96344f62bff7d4baf\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610716806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80631ab6dcab14610051578063a459600e14610086578063e795524414610099578063f32078e8146100a1575b600080fd5b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a688224991302545b60405190815260200160405180910390f35b610074610094366004610550565b6100b4565b6100746100e8565b6100746100af366004610569565b61011a565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6100e1818461018a565b9392505050565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff610114816101e4565b91505090565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905061018284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506102059050565b949350505050565b600082600301546000146101bd578260000182815481106101ad576101ad6105db565b90600052602060002001546100e1565b8260010182815481106101d2576101d26105db565b90600052602060002001549392505050565b600081600301546000146101f95781546101ff565b60018201545b92915050565b60006100e18383336000807fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c905084600201548451111561028c5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640160405180910390fd5b610295816103b7565b156102a3576102a38561048f565b600085600301546000146102ba57856001016102bc565b855b905060006102c9836104ae565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161036e9190610607565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516103a29392919061061e565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103df576103df61068a565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156104105761041061068a565b148015610425575061042281836106a0565b42115b15610484576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f91610471916106b8565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156104a05760006104a3565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561051a5761051a61068a565b905060008160028111156105305761053061068a565b14610545576105408260016106a0565b610547565b815b95945050505050565b60006020828403121561056257600080fd5b5035919050565b6000806020838503121561057c57600080fd5b823567ffffffffffffffff8082111561059457600080fd5b818501915085601f8301126105a857600080fd5b8135818111156105b757600080fd5b8660208285010111156105c957600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610619576106196105f1565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561066057858101830151858201608001528201610644565b81811115610672576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156106b3576106b36105f1565b500190565b60208101600383106106da57634e487b7160e01b600052602160045260246000fd5b9190529056fea2646970667358221220328b3d40c2b88f03954e8a7f51cfbded83c0547d5c86b90b0e45461f059f9f1064736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80631ab6dcab14610051578063a459600e14610086578063e795524414610099578063f32078e8146100a1575b600080fd5b7f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a688224991302545b60405190815260200160405180910390f35b610074610094366004610550565b6100b4565b6100746100e8565b6100746100af366004610569565b61011a565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff6100e1818461018a565b9392505050565b60007f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff610114816101e4565b91505090565b6000807f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff905061018284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506102059050565b949350505050565b600082600301546000146101bd578260000182815481106101ad576101ad6105db565b90600052602060002001546100e1565b8260010182815481106101d2576101d26105db565b90600052602060002001549392505050565b600081600301546000146101f95781546101ff565b60018201545b92915050565b60006100e18383336000807fd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189c905084600201548451111561028c5760405162461bcd60e51b815260206004820152601860248201527f696e707574206c656e3a205b302c647269766553697a655d0000000000000000604482015260640160405180910390fd5b610295816103b7565b156102a3576102a38561048f565b600085600301546000146102ba57856001016102bc565b855b905060006102c9836104ae565b8254604080516001600160a01b03891660208083019190915243828401524260608301526080820185905260a08083018590528351808403909101815260c0830184528051908201208b518c83012060e0840182905261010080850182905285518086039091018152610120909401909452825192820192909220600180860189556000898152929092209094018490558654949550909391929161036e9190610607565b847fa15a0da5519c084484141aaa73e525cee96062f5decc97e070f0c4da27738bc78a428d6040516103a29392919061061e565b60405180910390a39998505050505050505050565b60018101546000908190600160801b900463ffffffff1660028111156103df576103df61068a565b600184015490915063ffffffff6801000000000000000082048116911660008360028111156104105761041061068a565b148015610425575061042281836106a0565b42115b15610484576001858101805463ffffffff60801b1916600160801b1790556040517fed606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f91610471916106b8565b60405180910390a1506001949350505050565b506000949350505050565b6003810154156104a05760006104a3565b60015b60ff16600390910155565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff16600281111561051a5761051a61068a565b905060008160028111156105305761053061068a565b14610545576105408260016106a0565b610547565b815b95945050505050565b60006020828403121561056257600080fd5b5035919050565b6000806020838503121561057c57600080fd5b823567ffffffffffffffff8082111561059457600080fd5b818501915085601f8301126105a857600080fd5b8135818111156105b757600080fd5b8660208285010111156105c957600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610619576106196105f1565b500390565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b8181101561066057858101830151858201608001528201610644565b81811115610672576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052602160045260246000fd5b600082198211156106b3576106b36105f1565b500190565b60208101600383106106da57634e487b7160e01b600052602160045260246000fd5b9190529056fea2646970667358221220328b3d40c2b88f03954e8a7f51cfbded83c0547d5c86b90b0e45461f059f9f1064736f6c634300080d0033", - "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": "Indicates that an input was added to the accumulating epoch's inbox" - } - }, - "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/deployments/localhost/Merkle.json b/deployments/localhost/Merkle.json index 37071b0..3a4cff4 100644 --- a/deployments/localhost/Merkle.json +++ b/deployments/localhost/Merkle.json @@ -141,19 +141,19 @@ "type": "function" } ], - "transactionHash": "0x1934cf4da62448575fdf7486c4b710ca15c62732f6af72b4834a9d9e164fe9ae", + "transactionHash": "0x8f11a77a58a400f3d5db5b3bd8116617170a8c489b4562bbc2782056c7022097", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "transactionIndex": 0, - "gasUsed": "553584", + "gasUsed": "553732", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe8b8c4bf83f70d0e539a61d41081d93196d4d60f37c899913476e201ffd90ced", - "transactionHash": "0x1934cf4da62448575fdf7486c4b710ca15c62732f6af72b4834a9d9e164fe9ae", + "blockHash": "0x7d6f2c75bd7994ef6f4b4cf36efad80d34c50f133b30d7d0e23cecc1d318ca00", + "transactionHash": "0x8f11a77a58a400f3d5db5b3bd8116617170a8c489b4562bbc2782056c7022097", "logs": [], "blockNumber": 2, - "cumulativeGasUsed": "553584", + "cumulativeGasUsed": "553732", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/MerkleV2.json b/deployments/localhost/MerkleV2.json index b46f09a..962e573 100644 --- a/deployments/localhost/MerkleV2.json +++ b/deployments/localhost/MerkleV2.json @@ -127,19 +127,19 @@ "type": "function" } ], - "transactionHash": "0x37f284595eda516283b4c643d28f94805ed6e67bf689f0772733100ce954cbb1", + "transactionHash": "0x642b780adb8768accfb15f31179f4d16c5d2c26c63348f33170f79b5bc919964", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", "transactionIndex": 0, - "gasUsed": "1269380", + "gasUsed": "1269736", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5edcb1402064d7a7b704306b653ed7d5f6f3e5538f1423b259d0c7b38dab847e", - "transactionHash": "0x37f284595eda516283b4c643d28f94805ed6e67bf689f0772733100ce954cbb1", + "blockHash": "0x79638c3f0415b3d9df40e2e944e7d1b64f9634a438bae5912cdce20e37c1ce1f", + "transactionHash": "0x642b780adb8768accfb15f31179f4d16c5d2c26c63348f33170f79b5bc919964", "logs": [], "blockNumber": 9, - "cumulativeGasUsed": "1269380", + "cumulativeGasUsed": "1269736", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/MineTimelock.json b/deployments/localhost/MineTimelock.json deleted file mode 100644 index c512b11..0000000 --- a/deployments/localhost/MineTimelock.json +++ /dev/null @@ -1,241 +0,0 @@ -{ - "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "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": "0x984c54391f6f9e9c54d8b6a68137fcbd906abe7ab07fcedaec06ed8f9f23caa9", - "receipt": { - "to": null, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "transactionIndex": 0, - "gasUsed": "907201", - "logsBloom": "0x00000000100000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000020000000000000100000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x103f93c24e2cb8ac5e8eb6181f2d2eb834bacf27787b4ee701a43b88ee6f2b7d", - "transactionHash": "0x984c54391f6f9e9c54d8b6a68137fcbd906abe7ab07fcedaec06ed8f9f23caa9", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 12, - "transactionHash": "0x984c54391f6f9e9c54d8b6a68137fcbd906abe7ab07fcedaec06ed8f9f23caa9", - "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0x103f93c24e2cb8ac5e8eb6181f2d2eb834bacf27787b4ee701a43b88ee6f2b7d" - } - ], - "blockNumber": 12, - "cumulativeGasUsed": "907201", - "status": 1, - "byzantium": true - }, - "args": [ - "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "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/deployments/localhost/OutputFacet.json b/deployments/localhost/OutputFacet.json deleted file mode 100644 index 5fecc1e..0000000 --- a/deployments/localhost/OutputFacet.json +++ /dev/null @@ -1,536 +0,0 @@ -{ - "address": "0xfE9874EecC53aC5076f5f9c81C880F36D7b52488", - "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" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_notice", - "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": "validateNotice", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x1c98c15dd63e4e2ff604729f7a3be63571b30e253890803cbbff61e4cb58af89", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "803716", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xff3a5c8b9dfd61be2b1ccd10a8a8a4cf3a54ef018b9935b7b7dd1b7b6d56885f", - "transactionHash": "0x1c98c15dd63e4e2ff604729f7a3be63571b30e253890803cbbff61e4cb58af89", - "logs": [], - "blockNumber": 24, - "cumulativeGasUsed": "803716", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_notice\",\"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\":\"validateNotice\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\"}},\"validateNotice(bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))\":{\"params\":{\"_notice\":\"notice to be verified\",\"_v\":\"validity proof for this notice\"},\"returns\":{\"_0\":\"true if notice is valid\"}}},\"version\":1},\"userdoc\":{\"events\":{\"VoucherExecuted(uint256)\":{\"notice\":\"Indicates that a voucher was executed\"}},\"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\"},\"validateNotice(bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))\":{\"notice\":\"validates notice\"}},\"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/CartesiMathV2.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 CartesiMathV2 {\\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 = n + 128;\\n _num = _num >> 128;\\n }\\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) {\\n n = n + 64;\\n _num = _num >> 64;\\n }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) {\\n n = n + 32;\\n _num = _num >> 32;\\n }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) {\\n n = n + 16;\\n _num = _num >> 16;\\n }\\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) {\\n n = n + 8;\\n _num = _num >> 8;\\n }\\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) {\\n n = n + 4;\\n _num = _num >> 4;\\n }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) {\\n n = n + 2;\\n _num = _num >> 2;\\n }\\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) {\\n n = n + 1;\\n }\\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 = n + 128;\\n _num = _num << 128;\\n }\\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 64;\\n _num = _num << 64;\\n }\\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 32;\\n _num = _num << 32;\\n }\\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 16;\\n _num = _num << 16;\\n }\\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 8;\\n _num = _num << 8;\\n }\\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 4;\\n _num = _num << 4;\\n }\\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 2;\\n _num = _num << 2;\\n }\\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) {\\n n = n + 1;\\n }\\n\\n return n;\\n }\\n}\\n\",\"keccak256\":\"0x3208110a6cde8f74d144dc962c70346ab0d232b613a82ac371f1ab7bcf99cd56\",\"license\":\"Apache-2.0\"},\"@cartesi/util/contracts/MerkleV2.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 \\\"./CartesiMathV2.sol\\\";\\n\\nlibrary MerkleV2 {\\n using CartesiMathV2 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 && _logSizeOfReplacement >= 3 && _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(siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement, \\\"Proof length does not match\\\");\\n\\n for (uint256 i; i < siblings.length; i++) {\\n if ((_position & (size << i)) == 0) {\\n _replacement = keccak256(abi.encodePacked(_replacement, siblings[i]));\\n } else {\\n _replacement = keccak256(abi.encodePacked(siblings[i], _replacement));\\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) public pure returns (bytes32) {\\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) public pure returns (bytes32) {\\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(size << L_WORD_SIZE >= _data.length, \\\"data is bigger than drive\\\");\\n // the stack depth is log2(_data.length / 8) + 2\\n uint256 stack_depth = 2 + ((_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) public pure returns (bytes32) {\\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) public pure returns (bytes32) {\\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(abi.encodePacked(hashes[i], hashes[i + 1]));\\n }\\n\\n return calculateRootFromPowerOfTwo(newHashes);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x315a8d0fde92e153209207f0ec3aee323bfddc1c6857c5f1e245c781ae98c2b8\",\"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 {MerkleV2} from \\\"@cartesi/util/contracts/MerkleV2.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 validates notice\\n /// @param _notice notice to be verified\\n /// @param _v validity proof for this notice\\n /// @return true if notice is valid\\n function validateNotice(\\n bytes calldata _notice,\\n OutputValidityProof calldata _v\\n ) public view override returns (bool) {\\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\\n\\n bytes memory encodedNotice = abi.encode(_notice);\\n\\n // reverts if validity proof doesnt match\\n isValidNoticeProof(\\n encodedNotice,\\n outputDS.epochHashes[_v.epochIndex],\\n _v\\n );\\n\\n return true;\\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 MerkleV2.getRootAfterReplacementInDrive(\\n getIntraDrivePosition(_v.inputIndex, KECCAK_LOG2_SIZE),\\n KECCAK_LOG2_SIZE,\\n _outputEpochLog2Size,\\n _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 = MerkleV2.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 MerkleV2.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(\\n uint256 _index,\\n uint256 _log2Size\\n ) public pure returns (uint256) {\\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\":\"0x70f3d2b67fecf7f043bcf3f687e637bbaeb393dd080770f3b51e2589949a578e\",\"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/// @notice Data used to prove the validity of an output (notices and vouchers)\\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 output metadata hashes of the related input\\n/// @param vouchersEpochRootHash merkle root of all voucher metadata hashes of the related epoch\\n/// @param noticesEpochRootHash merkle root of all notice metadata hashes of the related epoch\\n/// @param machineStateHash hash of the machine state claimed for the related 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 a voucher\\n /// @param _destination address of the target contract that will execute the payload\\n /// @param _payload payload to be executed by the destination contract, containing a method signature and ABI-encoded parameters\\n /// @param _v validity proof for the voucher\\n /// @return true if voucher was executed successfully\\n /// @dev vouchers can only be successfully executed one time, and only if the provided proof is valid\\n function executeVoucher(\\n address _destination,\\n bytes calldata _payload,\\n OutputValidityProof calldata _v\\n ) external returns (bool);\\n\\n /// @notice Validates a notice\\n /// @param _notice notice to be validated\\n /// @param _v validity proof for the notice\\n /// @return true if notice is valid\\n function validateNotice(\\n bytes calldata _notice,\\n OutputValidityProof calldata _v\\n ) external view 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 /// @notice Indicates that a voucher was executed\\n /// @param voucherPosition voucher unique identifier considering epoch, input and output indices\\n event VoucherExecuted(uint256 voucherPosition);\\n}\\n\",\"keccak256\":\"0xae833978db7f074f365604b19d5f185c1a14f08d1e85fee5319ce368d5e6f723\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610d8e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80636190d81e116100715780636190d81e146101405780638021be811461015357806383552b4d1461015a578063a238203614610181578063a981588a14610153578063f3af7efd1461018157600080fd5b806310517cfc146100ae5780633ad58a27146100d35780633c0d9958146100e85780634f8192c91461010a5780635e439a0c1461012d575b600080fd5b6100c06100bc366004610900565b1b90565b6040519081526020015b60405180910390f35b6100e66100e1366004610951565b610188565b005b6100c06100f6366004610a30565b608083901b604083901b1781179392505050565b61011d610118366004610aa5565b6101a1565b60405190151581526020016100ca565b6100e661013b366004610951565b610227565b61011d61014e366004610af7565b61023b565b60156100c0565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea567546100c0565b60256100c0565b61019c83838360a001356025601586610600565b505050565b6000807f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669050600085856040516020016101dc929190610ba8565b604051602081830303815290604052905061021b818360010186600001358154811061020a5761020a610bc4565b906000526020600020015486610188565b50600195945050505050565b61019c838383608001356025601586610600565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea568546000907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060ff16156102d05760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff1916600117905560006103087f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56690565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75549091507f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73906001600160a01b039081169089160361039c5760405162461bcd60e51b815260206004820152600f60248201526e3130b2103232b9ba34b730ba34b7b760891b60448201526064016102c7565b60008888886040516020016103b393929190610bda565b60405160208183030381529060405290506103f281846001018860000135815481106103e1576103e1610bc4565b906000526020600020015488610227565b60006020870135604090811b9088013560801b178735176040516303fbaf7360e01b81526004810186905260248101829052909150730165878A594ca255338adfa4d48449f69242Eb8F906303fbaf7390604401602060405180830381865af4158015610463573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104879190610c08565b156104d45760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f776564000000000000000060448201526064016102c7565b60008a6001600160a01b03168a8a6040516104f0929190610c31565b6000604051808303816000865af19150503d806000811461052d576040519150601f19603f3d011682016040523d82523d6000602084013e610532565b606091505b5050905080156105e7576040516306449da160e41b8152600481018690526024810183905260016044820152730165878A594ca255338adfa4d48449f69242Eb8F90636449da109060640160006040518083038186803b15801561059557600080fd5b505af41580156105a9573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc54826040516105de91815260200190565b60405180910390a15b955050505050600201805460ff19169055949350505050565b60408051608080840135602083015260a08401359282019290925260c0830135606082015286910160405160208183030381529060405280519060200120146106815760405162461bcd60e51b8152602060048201526013602482015272195c1bd8da12185cda081a5b98dbdc9c9958dd606a1b60448201526064016102c7565b83732279B7A0a67DB372996a5FaB50D91eAA73d2eBe66379de4601602084013560051b60058760608701356106ba610100890189610c41565b6040518763ffffffff1660e01b81526004016106db96959493929190610c8b565b602060405180830381865af41580156106f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071c9190610ce2565b146107695760405162461bcd60e51b815260206004820152601e60248201527f6f75747075747345706f6368526f6f744861736820696e636f7272656374000060448201526064016102c7565b6000732279B7A0a67DB372996a5FaB50D91eAA73d2eBe663c84583a1888051906020012060405160200161079f91815260200190565b60405160208183030381529060405260056040518363ffffffff1660e01b81526004016107cd929190610cfb565b602060405180830381865af41580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190610ce2565b90506060820135732279B7A0a67DB372996a5FaB50D91eAA73d2eBe66379de4601604085013560051b6005878661084860e08a018a610c41565b6040518763ffffffff1660e01b815260040161086996959493929190610c8b565b602060405180830381865af4158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190610ce2565b146108f75760405162461bcd60e51b815260206004820152601e60248201527f6f7574707574486173686573526f6f744861736820696e636f7272656374000060448201526064016102c7565b50505050505050565b6000806040838503121561091357600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b6000610120828403121561094b57600080fd5b50919050565b60008060006060848603121561096657600080fd5b833567ffffffffffffffff8082111561097e57600080fd5b818601915086601f83011261099257600080fd5b8135818111156109a4576109a4610922565b604051601f8201601f19908116603f011681019083821181831017156109cc576109cc610922565b816040528281528960208487010111156109e557600080fd5b82602086016020830137600060208483010152809750505050602086013593506040860135915080821115610a1957600080fd5b50610a2686828701610938565b9150509250925092565b600080600060608486031215610a4557600080fd5b505081359360208301359350604090920135919050565b60008083601f840112610a6e57600080fd5b50813567ffffffffffffffff811115610a8657600080fd5b602083019150836020828501011115610a9e57600080fd5b9250929050565b600080600060408486031215610aba57600080fd5b833567ffffffffffffffff80821115610ad257600080fd5b610ade87838801610a5c565b90955093506020860135915080821115610a1957600080fd5b60008060008060608587031215610b0d57600080fd5b84356001600160a01b0381168114610b2457600080fd5b9350602085013567ffffffffffffffff80821115610b4157600080fd5b610b4d88838901610a5c565b90955093506040870135915080821115610b6657600080fd5b50610b7387828801610938565b91505092959194509250565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000610bbc602083018486610b7f565b949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152604060208201819052600090610bff9083018486610b7f565b95945050505050565b600060208284031215610c1a57600080fd5b81518015158114610c2a57600080fd5b9392505050565b8183823760009101908152919050565b6000808335601e19843603018112610c5857600080fd5b83018035915067ffffffffffffffff821115610c7357600080fd5b6020019150600581901b3603821315610a9e57600080fd5b86815285602082015284604082015283606082015260a060808201528160a0820152600060018060fb1b03831115610cc257600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b600060208284031215610cf457600080fd5b5051919050565b604081526000835180604084015260005b81811015610d295760208187018101516060868401015201610d0c565b81811115610d3b576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fea2646970667358221220ad5c61aba771b46ff01db2fa849e0f8aa8bcee012d38053cb75c41a9f14b7cdf64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80636190d81e116100715780636190d81e146101405780638021be811461015357806383552b4d1461015a578063a238203614610181578063a981588a14610153578063f3af7efd1461018157600080fd5b806310517cfc146100ae5780633ad58a27146100d35780633c0d9958146100e85780634f8192c91461010a5780635e439a0c1461012d575b600080fd5b6100c06100bc366004610900565b1b90565b6040519081526020015b60405180910390f35b6100e66100e1366004610951565b610188565b005b6100c06100f6366004610a30565b608083901b604083901b1781179392505050565b61011d610118366004610aa5565b6101a1565b60405190151581526020016100ca565b6100e661013b366004610951565b610227565b61011d61014e366004610af7565b61023b565b60156100c0565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea567546100c0565b60256100c0565b61019c83838360a001356025601586610600565b505050565b6000807f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669050600085856040516020016101dc929190610ba8565b604051602081830303815290604052905061021b818360010186600001358154811061020a5761020a610bc4565b906000526020600020015486610188565b50600195945050505050565b61019c838383608001356025601586610600565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea568546000907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060ff16156102d05760405162461bcd60e51b81526020600482015260166024820152751c99595b9d1c985b98de481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60028101805460ff1916600117905560006103087f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56690565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc75549091507f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc73906001600160a01b039081169089160361039c5760405162461bcd60e51b815260206004820152600f60248201526e3130b2103232b9ba34b730ba34b7b760891b60448201526064016102c7565b60008888886040516020016103b393929190610bda565b60405160208183030381529060405290506103f281846001018860000135815481106103e1576103e1610bc4565b906000526020600020015488610227565b60006020870135604090811b9088013560801b178735176040516303fbaf7360e01b8152600481018690526024810182905290915073__$f57eb21c11c6dae369da3ca36f4f48eb77$__906303fbaf7390604401602060405180830381865af4158015610463573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104879190610c08565b156104d45760405162461bcd60e51b815260206004820152601860248201527f72652d657865637574696f6e206e6f7420616c6c6f776564000000000000000060448201526064016102c7565b60008a6001600160a01b03168a8a6040516104f0929190610c31565b6000604051808303816000865af19150503d806000811461052d576040519150601f19603f3d011682016040523d82523d6000602084013e610532565b606091505b5050905080156105e7576040516306449da160e41b815260048101869052602481018390526001604482015273__$f57eb21c11c6dae369da3ca36f4f48eb77$__90636449da109060640160006040518083038186803b15801561059557600080fd5b505af41580156105a9573d6000803e3d6000fd5b505050507f0eb7ee080f865f1cadc4f54daf58cc3b8879e888832867d13351edcec0fbdc54826040516105de91815260200190565b60405180910390a15b955050505050600201805460ff19169055949350505050565b60408051608080840135602083015260a08401359282019290925260c0830135606082015286910160405160208183030381529060405280519060200120146106815760405162461bcd60e51b8152602060048201526013602482015272195c1bd8da12185cda081a5b98dbdc9c9958dd606a1b60448201526064016102c7565b8373__$2a7ef22e717e9afc55afc95d018bf1a85b$__6379de4601602084013560051b60058760608701356106ba610100890189610c41565b6040518763ffffffff1660e01b81526004016106db96959493929190610c8b565b602060405180830381865af41580156106f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071c9190610ce2565b146107695760405162461bcd60e51b815260206004820152601e60248201527f6f75747075747345706f6368526f6f744861736820696e636f7272656374000060448201526064016102c7565b600073__$2a7ef22e717e9afc55afc95d018bf1a85b$__63c84583a1888051906020012060405160200161079f91815260200190565b60405160208183030381529060405260056040518363ffffffff1660e01b81526004016107cd929190610cfb565b602060405180830381865af41580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190610ce2565b9050606082013573__$2a7ef22e717e9afc55afc95d018bf1a85b$__6379de4601604085013560051b6005878661084860e08a018a610c41565b6040518763ffffffff1660e01b815260040161086996959493929190610c8b565b602060405180830381865af4158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190610ce2565b146108f75760405162461bcd60e51b815260206004820152601e60248201527f6f7574707574486173686573526f6f744861736820696e636f7272656374000060448201526064016102c7565b50505050505050565b6000806040838503121561091357600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b6000610120828403121561094b57600080fd5b50919050565b60008060006060848603121561096657600080fd5b833567ffffffffffffffff8082111561097e57600080fd5b818601915086601f83011261099257600080fd5b8135818111156109a4576109a4610922565b604051601f8201601f19908116603f011681019083821181831017156109cc576109cc610922565b816040528281528960208487010111156109e557600080fd5b82602086016020830137600060208483010152809750505050602086013593506040860135915080821115610a1957600080fd5b50610a2686828701610938565b9150509250925092565b600080600060608486031215610a4557600080fd5b505081359360208301359350604090920135919050565b60008083601f840112610a6e57600080fd5b50813567ffffffffffffffff811115610a8657600080fd5b602083019150836020828501011115610a9e57600080fd5b9250929050565b600080600060408486031215610aba57600080fd5b833567ffffffffffffffff80821115610ad257600080fd5b610ade87838801610a5c565b90955093506020860135915080821115610a1957600080fd5b60008060008060608587031215610b0d57600080fd5b84356001600160a01b0381168114610b2457600080fd5b9350602085013567ffffffffffffffff80821115610b4157600080fd5b610b4d88838901610a5c565b90955093506040870135915080821115610b6657600080fd5b50610b7387828801610938565b91505092959194509250565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000610bbc602083018486610b7f565b949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152604060208201819052600090610bff9083018486610b7f565b95945050505050565b600060208284031215610c1a57600080fd5b81518015158114610c2a57600080fd5b9392505050565b8183823760009101908152919050565b6000808335601e19843603018112610c5857600080fd5b83018035915067ffffffffffffffff821115610c7357600080fd5b6020019150600581901b3603821315610a9e57600080fd5b86815285602082015284604082015283606082015260a060808201528160a0820152600060018060fb1b03831115610cc257600080fd5b8260051b808560c08501376000920160c001918252509695505050505050565b600060208284031215610cf457600080fd5b5051919050565b604081526000835180604084015260005b81811015610d295760208187018101516060868401015201610d0c565b81811115610d3b576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fea2646970667358221220ad5c61aba771b46ff01db2fa849e0f8aa8bcee012d38053cb75c41a9f14b7cdf64736f6c634300080d0033", - "libraries": { - "Bitmask": "0x0165878A594ca255338adfa4d48449f69242Eb8F", - "MerkleV2": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" - }, - "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" - } - }, - "validateNotice(bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))": { - "params": { - "_notice": "notice to be verified", - "_v": "validity proof for this notice" - }, - "returns": { - "_0": "true if notice is valid" - } - } - }, - "version": 1 - }, - "userdoc": { - "events": { - "VoucherExecuted(uint256)": { - "notice": "Indicates that a voucher was executed" - } - }, - "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" - }, - "validateNotice(bytes,(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,bytes32[],bytes32[]))": { - "notice": "validates notice" - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/localhost/OwnershipFacet.json b/deployments/localhost/OwnershipFacet.json deleted file mode 100644 index de6c244..0000000 --- a/deployments/localhost/OwnershipFacet.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "address": "0x19C65463Eb32Ff190062686b4ce150Ea1BD80988", - "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": "0x2cd630b95e79478f0c9ba74cf23d2261c36b9847102cbf13b6af69589ac20bb1", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "179922", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1d21f5e47d5b20423f0971cf40bb851f672679d6de8cacc37ea4e08a0a4afe89", - "transactionHash": "0x2cd630b95e79478f0c9ba74cf23d2261c36b9847102cbf13b6af69589ac20bb1", - "logs": [], - "blockNumber": 18, - "cumulativeGasUsed": "179922", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\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\":\"0x581eb846bee3d62731f4fc5bf21aa9cf744f491075941de685797f107e5d06f2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610248806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461005f575b600080fd5b610043610074565b6040516001600160a01b03909116815260200160405180910390f35b61007261006d3660046101e2565b6100ac565b005b60006100a77fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031690565b905090565b6100b46100c0565b6100bd8161014d565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b0316331461014b5760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6000602082840312156101f457600080fd5b81356001600160a01b038116811461020b57600080fd5b939250505056fea2646970667358221220eae4262b777d15dea997f7bd72219d30a5dfbe4f129ce658f38c2f6db472de0d64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461005f575b600080fd5b610043610074565b6040516001600160a01b03909116815260200160405180910390f35b61007261006d3660046101e2565b6100ac565b005b60006100a77fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031690565b905090565b6100b46100c0565b6100bd8161014d565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b0316331461014b5760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b038481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6000602082840312156101f457600080fd5b81356001600160a01b038116811461020b57600080fd5b939250505056fea2646970667358221220eae4262b777d15dea997f7bd72219d30a5dfbe4f129ce658f38c2f6db472de0d64736f6c634300080d0033", - "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/deployments/localhost/RollupsFacet.json b/deployments/localhost/RollupsFacet.json deleted file mode 100644 index 9012b0e..0000000 --- a/deployments/localhost/RollupsFacet.json +++ /dev/null @@ -1,292 +0,0 @@ -{ - "address": "0x98Bd941FFa18D10328eF1dea76a146AB6FD78Ee4", - "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": "0xcbe2f3fd60d8591a2b600f169468385e4416065aa5447d903907a749fafedcfa", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "1330039", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x25c18081501fe08282673598dd2f7a4fddb79090ff233c09dce93459a9653e90", - "transactionHash": "0xcbe2f3fd60d8591a2b600f169468385e4416065aa5447d903907a749fafedcfa", - "logs": [], - "blockNumber": 25, - "cumulativeGasUsed": "1330039", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (bytes32) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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(\\n DiamondStorage storage ds,\\n bytes memory input\\n ) internal returns (bytes32) {\\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\":\"0xbef9e65047564508f5b0c800f302d9d0b0757126968baf02e8f84a2563b2830a\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.epochHashes.length;\\n }\\n}\\n\",\"keccak256\":\"0xfecf86b891ef3dff302531a042fbcf25c4638cb2cb64497f3c20231cfe04ccf9\",\"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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\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\":\"0x6455b49596bcc13c3d87869f6795fb747f38efe784f8fc504572f8fb16c00f30\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061170f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063a3a40ea511610066578063a3a40ea51461010b578063b97dd9e214610120578063bd66528a14610128578063ddf7bcf01461013b578063e17ba0121461015d57600080fd5b806354ee1da51461009857806361b12c66146100c95780637864b77d146100de57806382ae9ef714610101575b600080fd5b60008051602061165a83398151915254600160601b900463ffffffff165b6040519081526020015b60405180910390f35b6000805160206116ba833981519152546100b6565b60008051602061165a83398151915254640100000000900463ffffffff166100b6565b610109610178565b005b610113610304565b6040516100c091906114fb565b6100b661034b565b61010961013636600461150e565b610365565b60008051602061165a83398151915254600160401b900463ffffffff166100b6565b60008051602061165a8339815191525463ffffffff166100b6565b60008051602061165a833981519152546000805160206116ba8339815191529060008051602061169a83398151915290600090600160801b900463ffffffff1660028111156101c9576101c96114c7565b905060018160028111156101df576101df6114c7565b146102315760405162461bcd60e51b815260206004820152601b60248201527f506861736520213d204177616974696e6720436f6e73656e737573000000000060448201526064015b60405180910390fd5b600183015463ffffffff600160601b8204811691640100000000900416610258818361153d565b42116102a65760405162461bcd60e51b815260206004820152601960248201527f4368616c6c656e676520706572696f64206e6f74206f766572000000000000006044820152606401610228565b83546102f45760405162461bcd60e51b815260206004820152601860248201527f4e6f20436c61696d20746f2062652066696e616c697a656400000000000000006044820152606401610228565b6102fd8561057f565b5050505050565b60008051602061165a833981519152546000906000805160206116ba83398151915290600160801b900463ffffffff166002811115610345576103456114c7565b91505090565b60006000805160206116ba833981519152610345816106b7565b6000805160206116ba8339815191527f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56660008051602061169a83398151915260006103cf611477565b6103d7611477565b6001870154600090600160801b900463ffffffff1660028111156103fd576103fd6114c7565b600189015490915063ffffffff600160401b8204811691166000836002811115610429576104296114c7565b14801561043e575061043b818361153d565b42115b156104af5760018a8101805463ffffffff60801b1916600160801b17905560405190935060008051602061167a8339815191529061047d9085906114fb565b60405180910390a161048e89610759565b60018a01805463ffffffff60601b1916600160601b4263ffffffff16021790555b60018360028111156104c3576104c36114c7565b146105105760405162461bcd60e51b815260206004820152601a60248201527f506861736520213d204177616974696e67436f6e73656e7375730000000000006044820152606401610228565b61051b87338d610765565b9197509550935061052d886001015490565b60408051338152602081018e90527fd31325e5dc55b03edf08c70299d3b1bc8d4c2ca8512c90138ddd03e3f54fce6c910160405180910390a26105728a878787610986565b5050505050505050505050565b60018101805463ffffffff60801b191690556040517f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060008051602061169a8339815191529060008051602061167a83398151915290610604906000906114fb565b60405180910390a160018401805463ffffffff60601b1963ffffffff4216600160401b02166fffffffffffffffff0000000000000000199091161763ffffffff60601b179055600061065582610adc565b9050610662836001015490565b6040518281527f6e3d05bc77b9307d9ba574c7c3196a746edd51104ded1c823edc63be4b8a63c39060200160405180910390a2600180840180549182018155600090815260209020018190556102fd84610b39565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff166002811115610723576107236114c7565b90506000816002811115610739576107396114c7565b1461074e5761074982600161153d565b610750565b815b95945050505050565b61076281610b5c565b50565b600061076f611477565b610777611477565b836107b25760405162461bcd60e51b815260206004820152600b60248201526a656d70747920636c61696d60a81b6044820152606401610228565b6107bc8686610b7b565b6107fd5760405162461bcd60e51b81526020600482015260126024820152711cd95b99195c881b9bdd08185b1b1bddd95960721b6044820152606401610228565b60006108098787610c2a565b600388015490915060f81c811c600116156108765760405162461bcd60e51b815260206004820152602760248201527f73656e6465722068616420636c61696d656420696e20746869732065706f6368604482015266206265666f726560c81b6064820152608401610228565b8654610884578487556108e4565b865485146108e4576108d8600260405180604001604052808a6000015481526020018881525060405180604001604052806108be8c610d09565b6001600160a01b0390811682528b16602090910152610dc3565b9350935093505061097d565b6108ee8787610e1c565b6108f787610e47565b61093b576040805180820182528681526000602080830182905283518085019094526001600160a01b038a168452830181905261093692909190610dc3565b610975565b6040805180820182528681526000602080830182905283518085019094526001600160a01b038a1684528301526109759160019190610dc3565b935093509350505b93509350939050565b600083600281111561099a5761099a6114c7565b03610a24576001840154600090600160801b900463ffffffff1660028111156109c5576109c56114c7565b905060018160028111156109db576109db6114c7565b14610a1e576001858101805463ffffffff60801b1916600160801b17905560405160008051602061167a83398151915291610a15916114fb565b60405180910390a15b50610ad6565b6001836002811115610a3857610a386114c7565b03610a4b57610a468461057f565b610ad6565b6001840154600090600160801b900463ffffffff166002811115610a7157610a716114c7565b90506002816002811115610a8757610a876114c7565b14610acc5760018501805463ffffffff60801b1916600160811b17905560405160008051602061167a83398151915290610ac3906002906114fb565b60405180910390a15b6102fd8383610e69565b50505050565b6000610ae782610e92565b81546000835560038301546001600160f81b031660038401556040518181527fddc860800a99149017c480ec51523bf4143b7215e78956ae5c31e5c568f5383a9060200160405180910390a192915050565b600381015415610b4e57610762816000611495565b610762600182016000611495565b600381015415610b6d576000610b70565b60015b60ff16600390910155565b60006001600160a01b038216610bbf5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610c1e57836001018181548110610be357610be3611555565b6000918252602090912001546001600160a01b0390811690841603610c0c576001915050610c24565b80610c168161156b565b915050610bc2565b50600090505b92915050565b60006001600160a01b038216610c6e5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610cca57836001018181548110610c9257610c92611555565b6000918252602090912001546001600160a01b0390811690841603610cb8579050610c24565b80610cc28161156b565b915050610c71565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b6044820152606401610228565b600080610d1a836003015460f81c90565b905060005b6001840154811015610d7a576001811b821615610d6857836001018181548110610d4b57610d4b611555565b6000918252602090912001546001600160a01b0316949350505050565b80610d728161156b565b915050610d1f565b5060405162461bcd60e51b815260206004820152601c60248201527f4167726565696e672076616c696461746f72206e6f7420666f756e64000000006044820152606401610228565b6000610dcd611477565b610dd5611477565b7f495383aed97965c56495cdbadedfe9667a1b028c54d3fc4b5335895146e02b70868686604051610e0893929190611584565b60405180910390a150939492935090919050565b6000610e288383610c2a565b6003840154909150610e3a9082610ee7565b8360030181905550505050565b600381015460009060f081901c60ff16610e618260f81c90565b149392505050565b8051602082015183516000805160206116ba83398151915292610e8d928492610f25565b505050565b6000610ea2826003015460f81c90565b905060005b6001830154811015610e8d576001811b821615610ed5576003830154610ecf90826001610fdb565b60038401555b80610edf8161156b565b915050610ea7565b600060088210610f095760405162461bcd60e51b8152600401610228906115f7565b6000610f168360f861153d565b6001901b841791505092915050565b6000610f2f611477565b610f37611477565b60008051602061169a833981519152610f528188888861102e565b60018b01805463ffffffff60601b1916600160601b4263ffffffff1602179055604080516001600160a01b03808d1682528b16602082015290810189905292965090945092507f2afbde4d47160a9c5de25b0df88d5b83e705286f2a447cac162db5e99ad6f5d29060600160405180910390a1610fd188858585610986565b5050505050505050565b600060088310610ffd5760405162461bcd60e51b8152600401610228906115f7565b600061100985856111e2565b90506000611017848361153d565b9050611024868683611230565b9695505050505050565b6000611038611477565b611040611477565b61104a87866112e4565b865484036110e45761105b87610e47565b61109f576040805180820182528581526000602080830182905283518085019094526001600160a01b038a168452830181905261109a929091906113b8565b6110d9565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526110d991600191906113b8565b9250925092506111d8565b600387015460f81c1561113d576110d9600260405180604001604052808a6000015481526020018781525060405180604001604052806111238c610d09565b6001600160a01b0390811682528b166020909101526113b8565b83875561114a8787610e1c565b61115387610e47565b611197576040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301819052611192929091906113b8565b6111d1565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526111d191600191906113b8565b9250925092505b9450945094915050565b6000600882106112045760405162461bcd60e51b8152600401610228906115f7565b600061121560016340000000611623565b90508061122384601e61163a565b85901c1691505092915050565b6000600883106112525760405162461bcd60e51b8152600401610228906115f7565b61126160016340000000611623565b8211156112a65760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b6044820152606401610228565b60006112b384601e61163a565b6112c260016340000000611623565b901b1990508481166112d585601e61163a565b9390931b909217949350505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7360005b6001840154811015610ad65783600101818154811061132957611329611555565b6000918252602090912001546001600160a01b03908116908416036113a657600084600101828154811061135f5761135f611555565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600384015461139790826113fd565b6003850155610a46828261145a565b806113b08161156b565b915050611308565b60006113c2611477565b6113ca611477565b7f09201c193a07cae1df95ae692cc698685574c942a04514c48a4c3249f38594ff868686604051610e0893929190611584565b60006008821061141f5760405162461bcd60e51b8152600401610228906115f7565b82600061142d8460f861153d565b6001901b199182169190506114438460f061153d565b6001901b1991821691905061075082856000611230565b600382015461146b90826000611230565b82600301819055505050565b60405180604001604052806002906020820280368337509192915050565b508054600082559060005260206000209081019061076291905b808211156114c357600081556001016114af565b5090565b634e487b7160e01b600052602160045260246000fd5b6003811061076257634e487b7160e01b600052602160045260246000fd5b60208101611508836114dd565b91905290565b60006020828403121561152057600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561155057611550611527565b500190565b634e487b7160e01b600052603260045260246000fd5b60006001820161157d5761157d611527565b5060010190565b60a08101611591856114dd565b84825260208083018560005b60028110156115ba5781518352918301919083019060010161159d565b505050606083018460005b60028110156115eb5781516001600160a01b0316835291830191908301906001016115c5565b50505050949350505050565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b60008282101561163557611635611527565b500390565b600081600019048311821515161561165457611654611527565b50029056fed32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ded606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fcd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ca2646970667358221220dfa28d663e8a5f4685cbe6ced410bf3adbb150ac3d2c9e23be55fbb383f68bd864736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063a3a40ea511610066578063a3a40ea51461010b578063b97dd9e214610120578063bd66528a14610128578063ddf7bcf01461013b578063e17ba0121461015d57600080fd5b806354ee1da51461009857806361b12c66146100c95780637864b77d146100de57806382ae9ef714610101575b600080fd5b60008051602061165a83398151915254600160601b900463ffffffff165b6040519081526020015b60405180910390f35b6000805160206116ba833981519152546100b6565b60008051602061165a83398151915254640100000000900463ffffffff166100b6565b610109610178565b005b610113610304565b6040516100c091906114fb565b6100b661034b565b61010961013636600461150e565b610365565b60008051602061165a83398151915254600160401b900463ffffffff166100b6565b60008051602061165a8339815191525463ffffffff166100b6565b60008051602061165a833981519152546000805160206116ba8339815191529060008051602061169a83398151915290600090600160801b900463ffffffff1660028111156101c9576101c96114c7565b905060018160028111156101df576101df6114c7565b146102315760405162461bcd60e51b815260206004820152601b60248201527f506861736520213d204177616974696e6720436f6e73656e737573000000000060448201526064015b60405180910390fd5b600183015463ffffffff600160601b8204811691640100000000900416610258818361153d565b42116102a65760405162461bcd60e51b815260206004820152601960248201527f4368616c6c656e676520706572696f64206e6f74206f766572000000000000006044820152606401610228565b83546102f45760405162461bcd60e51b815260206004820152601860248201527f4e6f20436c61696d20746f2062652066696e616c697a656400000000000000006044820152606401610228565b6102fd8561057f565b5050505050565b60008051602061165a833981519152546000906000805160206116ba83398151915290600160801b900463ffffffff166002811115610345576103456114c7565b91505090565b60006000805160206116ba833981519152610345816106b7565b6000805160206116ba8339815191527f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea56660008051602061169a83398151915260006103cf611477565b6103d7611477565b6001870154600090600160801b900463ffffffff1660028111156103fd576103fd6114c7565b600189015490915063ffffffff600160401b8204811691166000836002811115610429576104296114c7565b14801561043e575061043b818361153d565b42115b156104af5760018a8101805463ffffffff60801b1916600160801b17905560405190935060008051602061167a8339815191529061047d9085906114fb565b60405180910390a161048e89610759565b60018a01805463ffffffff60601b1916600160601b4263ffffffff16021790555b60018360028111156104c3576104c36114c7565b146105105760405162461bcd60e51b815260206004820152601a60248201527f506861736520213d204177616974696e67436f6e73656e7375730000000000006044820152606401610228565b61051b87338d610765565b9197509550935061052d886001015490565b60408051338152602081018e90527fd31325e5dc55b03edf08c70299d3b1bc8d4c2ca8512c90138ddd03e3f54fce6c910160405180910390a26105728a878787610986565b5050505050505050505050565b60018101805463ffffffff60801b191690556040517f943d5d24442f02461445e15c5d7d4a4ef0acb0d32c5d6f6af37a6882249912ff907f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5669060008051602061169a8339815191529060008051602061167a83398151915290610604906000906114fb565b60405180910390a160018401805463ffffffff60601b1963ffffffff4216600160401b02166fffffffffffffffff0000000000000000199091161763ffffffff60601b179055600061065582610adc565b9050610662836001015490565b6040518281527f6e3d05bc77b9307d9ba574c7c3196a746edd51104ded1c823edc63be4b8a63c39060200160405180910390a2600180840180549182018155600090815260209020018190556102fd84610b39565b7f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea5675460018201546000917f0635ad75fae4d4e8d896461a635d23700076a1c3fd8da26276f18cb1c09ea566918390600160801b900463ffffffff166002811115610723576107236114c7565b90506000816002811115610739576107396114c7565b1461074e5761074982600161153d565b610750565b815b95945050505050565b61076281610b5c565b50565b600061076f611477565b610777611477565b836107b25760405162461bcd60e51b815260206004820152600b60248201526a656d70747920636c61696d60a81b6044820152606401610228565b6107bc8686610b7b565b6107fd5760405162461bcd60e51b81526020600482015260126024820152711cd95b99195c881b9bdd08185b1b1bddd95960721b6044820152606401610228565b60006108098787610c2a565b600388015490915060f81c811c600116156108765760405162461bcd60e51b815260206004820152602760248201527f73656e6465722068616420636c61696d656420696e20746869732065706f6368604482015266206265666f726560c81b6064820152608401610228565b8654610884578487556108e4565b865485146108e4576108d8600260405180604001604052808a6000015481526020018881525060405180604001604052806108be8c610d09565b6001600160a01b0390811682528b16602090910152610dc3565b9350935093505061097d565b6108ee8787610e1c565b6108f787610e47565b61093b576040805180820182528681526000602080830182905283518085019094526001600160a01b038a168452830181905261093692909190610dc3565b610975565b6040805180820182528681526000602080830182905283518085019094526001600160a01b038a1684528301526109759160019190610dc3565b935093509350505b93509350939050565b600083600281111561099a5761099a6114c7565b03610a24576001840154600090600160801b900463ffffffff1660028111156109c5576109c56114c7565b905060018160028111156109db576109db6114c7565b14610a1e576001858101805463ffffffff60801b1916600160801b17905560405160008051602061167a83398151915291610a15916114fb565b60405180910390a15b50610ad6565b6001836002811115610a3857610a386114c7565b03610a4b57610a468461057f565b610ad6565b6001840154600090600160801b900463ffffffff166002811115610a7157610a716114c7565b90506002816002811115610a8757610a876114c7565b14610acc5760018501805463ffffffff60801b1916600160811b17905560405160008051602061167a83398151915290610ac3906002906114fb565b60405180910390a15b6102fd8383610e69565b50505050565b6000610ae782610e92565b81546000835560038301546001600160f81b031660038401556040518181527fddc860800a99149017c480ec51523bf4143b7215e78956ae5c31e5c568f5383a9060200160405180910390a192915050565b600381015415610b4e57610762816000611495565b610762600182016000611495565b600381015415610b6d576000610b70565b60015b60ff16600390910155565b60006001600160a01b038216610bbf5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610c1e57836001018181548110610be357610be3611555565b6000918252602090912001546001600160a01b0390811690841603610c0c576001915050610c24565b80610c168161156b565b915050610bc2565b50600090505b92915050565b60006001600160a01b038216610c6e5760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b6044820152606401610228565b60005b6001840154811015610cca57836001018181548110610c9257610c92611555565b6000918252602090912001546001600160a01b0390811690841603610cb8579050610c24565b80610cc28161156b565b915050610c71565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b6044820152606401610228565b600080610d1a836003015460f81c90565b905060005b6001840154811015610d7a576001811b821615610d6857836001018181548110610d4b57610d4b611555565b6000918252602090912001546001600160a01b0316949350505050565b80610d728161156b565b915050610d1f565b5060405162461bcd60e51b815260206004820152601c60248201527f4167726565696e672076616c696461746f72206e6f7420666f756e64000000006044820152606401610228565b6000610dcd611477565b610dd5611477565b7f495383aed97965c56495cdbadedfe9667a1b028c54d3fc4b5335895146e02b70868686604051610e0893929190611584565b60405180910390a150939492935090919050565b6000610e288383610c2a565b6003840154909150610e3a9082610ee7565b8360030181905550505050565b600381015460009060f081901c60ff16610e618260f81c90565b149392505050565b8051602082015183516000805160206116ba83398151915292610e8d928492610f25565b505050565b6000610ea2826003015460f81c90565b905060005b6001830154811015610e8d576001811b821615610ed5576003830154610ecf90826001610fdb565b60038401555b80610edf8161156b565b915050610ea7565b600060088210610f095760405162461bcd60e51b8152600401610228906115f7565b6000610f168360f861153d565b6001901b841791505092915050565b6000610f2f611477565b610f37611477565b60008051602061169a833981519152610f528188888861102e565b60018b01805463ffffffff60601b1916600160601b4263ffffffff1602179055604080516001600160a01b03808d1682528b16602082015290810189905292965090945092507f2afbde4d47160a9c5de25b0df88d5b83e705286f2a447cac162db5e99ad6f5d29060600160405180910390a1610fd188858585610986565b5050505050505050565b600060088310610ffd5760405162461bcd60e51b8152600401610228906115f7565b600061100985856111e2565b90506000611017848361153d565b9050611024868683611230565b9695505050505050565b6000611038611477565b611040611477565b61104a87866112e4565b865484036110e45761105b87610e47565b61109f576040805180820182528581526000602080830182905283518085019094526001600160a01b038a168452830181905261109a929091906113b8565b6110d9565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526110d991600191906113b8565b9250925092506111d8565b600387015460f81c1561113d576110d9600260405180604001604052808a6000015481526020018781525060405180604001604052806111238c610d09565b6001600160a01b0390811682528b166020909101526113b8565b83875561114a8787610e1c565b61115387610e47565b611197576040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301819052611192929091906113b8565b6111d1565b6040805180820182528581526000602080830182905283518085019094526001600160a01b038a1684528301526111d191600191906113b8565b9250925092505b9450945094915050565b6000600882106112045760405162461bcd60e51b8152600401610228906115f7565b600061121560016340000000611623565b90508061122384601e61163a565b85901c1691505092915050565b6000600883106112525760405162461bcd60e51b8152600401610228906115f7565b61126160016340000000611623565b8211156112a65760405162461bcd60e51b8152602060048201526013602482015272436c61696d734d61736b204f766572666c6f7760681b6044820152606401610228565b60006112b384601e61163a565b6112c260016340000000611623565b901b1990508481166112d585601e61163a565b9390931b909217949350505050565b7f844e22529543d6e722c6477171dd50ffe5b412198b92cd9aeea62bbfabe4cc7360005b6001840154811015610ad65783600101818154811061132957611329611555565b6000918252602090912001546001600160a01b03908116908416036113a657600084600101828154811061135f5761135f611555565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600384015461139790826113fd565b6003850155610a46828261145a565b806113b08161156b565b915050611308565b60006113c2611477565b6113ca611477565b7f09201c193a07cae1df95ae692cc698685574c942a04514c48a4c3249f38594ff868686604051610e0893929190611584565b60006008821061141f5760405162461bcd60e51b8152600401610228906115f7565b82600061142d8460f861153d565b6001901b199182169190506114438460f061153d565b6001901b1991821691905061075082856000611230565b600382015461146b90826000611230565b82600301819055505050565b60405180604001604052806002906020820280368337509192915050565b508054600082559060005260206000209081019061076291905b808211156114c357600081556001016114af565b5090565b634e487b7160e01b600052602160045260246000fd5b6003811061076257634e487b7160e01b600052602160045260246000fd5b60208101611508836114dd565b91905290565b60006020828403121561152057600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561155057611550611527565b500190565b634e487b7160e01b600052603260045260246000fd5b60006001820161157d5761157d611527565b5060010190565b60a08101611591856114dd565b84825260208083018560005b60028110156115ba5781518352918301919083019060010161159d565b505050606083018460005b60028110156115eb5781516001600160a01b0316835291830191908301906001016115c5565b50505050949350505050565b602080825260129082015271696e646578206f7574206f662072616e676560701b604082015260600190565b60008282101561163557611635611527565b500390565b600081600019048311821515161561165457611654611527565b50029056fed32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ded606d544c2202d032d2626c390923e6f260ca5d89625bba0cfe70d2bdda4e8f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fcd32d7f90491bee81172a406b65f3270d810392fe53bb0379dde8bdd4e624189ca2646970667358221220dfa28d663e8a5f4685cbe6ced410bf3adbb150ac3d2c9e23be55fbb383f68bd864736f6c634300080d0033", - "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/deployments/localhost/SimpleFaucet.json b/deployments/localhost/SimpleFaucet.json deleted file mode 100644 index 2426361..0000000 --- a/deployments/localhost/SimpleFaucet.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "address": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "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": "0x68f4d6ef6a083b3ff6a90dde16e286a48735afdc5e915c5fcc99886f75e1da30", - "receipt": { - "to": null, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "transactionIndex": 0, - "gasUsed": "280767", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfeea9ee4484aedb9764865497cfb76b14c0892428434d36da79f2325c8dadd4f", - "transactionHash": "0x68f4d6ef6a083b3ff6a90dde16e286a48735afdc5e915c5fcc99886f75e1da30", - "logs": [], - "blockNumber": 13, - "cumulativeGasUsed": "280767", - "status": 1, - "byzantium": true - }, - "args": [ - "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" - ], - "numDeployments": 1, - "bytecode": "0x608060405234801561001057600080fd5b506040516020806104758339810180604052602081101561003057600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506103a8806100cd6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80632d291cad1461005c578063359cf2b7146100b8578063658030b3146100c2578063ccca123b1461010c578063eec7faa11461012a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610148565b604051808215151515815260200191505060405180910390f35b6100c06101f5565b005b6100ca610342565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610114610367565b6040518082815260200191505060405180910390f35b61013261036e565b6040518082815260200191505060405180910390f35b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561019a57600190506101f0565b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421015156101eb57600190506101f0565b600090505b919050565b6101fe33610148565b151561020957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3369152d02c7e14af68000006040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156102bb57600080fd5b505af11580156102cf573d6000803e3d6000fd5b505050506040513d60208110156102e557600080fd5b8101908080519060200190929190505050506224ea004201600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6224ea0081565b69152d02c7e14af68000008156fea165627a7a723058201a95fe0177c1cf4bc787a7385da5ab9120c37ac47a5207b31bfe92023fefe3100029", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c80632d291cad1461005c578063359cf2b7146100b8578063658030b3146100c2578063ccca123b1461010c578063eec7faa11461012a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610148565b604051808215151515815260200191505060405180910390f35b6100c06101f5565b005b6100ca610342565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610114610367565b6040518082815260200191505060405180910390f35b61013261036e565b6040518082815260200191505060405180910390f35b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561019a57600190506101f0565b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421015156101eb57600190506101f0565b600090505b919050565b6101fe33610148565b151561020957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3369152d02c7e14af68000006040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156102bb57600080fd5b505af11580156102cf573d6000803e3d6000fd5b505050506040513d60208110156102e557600080fd5b8101908080519060200190929190505050506224ea004201600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6224ea0081565b69152d02c7e14af68000008156fea165627a7a723058201a95fe0177c1cf4bc787a7385da5ab9120c37ac47a5207b31bfe92023fefe3100029", - "devdoc": { - "methods": {} - }, - "userdoc": { - "methods": {} - } -} \ No newline at end of file diff --git a/deployments/localhost/UnrolledCordic.json b/deployments/localhost/UnrolledCordic.json index 2c3ce2a..1607032 100644 --- a/deployments/localhost/UnrolledCordic.json +++ b/deployments/localhost/UnrolledCordic.json @@ -21,19 +21,19 @@ "type": "function" } ], - "transactionHash": "0x83f9c126988513d614c388f2254b16a67fb808d1e1a36196813249a4baedd1f3", + "transactionHash": "0xc963a016467fb42432c4224633c851d4d5628693fe9343ca4e40e5be74cfd1a9", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", "transactionIndex": 0, - "gasUsed": "394712", + "gasUsed": "394816", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa7ef9a14361b12b8533e4845e8194e135590e955fb1db01ad68713df1348f6d9", - "transactionHash": "0x83f9c126988513d614c388f2254b16a67fb808d1e1a36196813249a4baedd1f3", + "blockHash": "0xe6d430078af4f2ddba081cc00558ca8f54d41af6ab767b3007eabd013180d2d3", + "transactionHash": "0xc963a016467fb42432c4224633c851d4d5628693fe9343ca4e40e5be74cfd1a9", "logs": [], "blockNumber": 10, - "cumulativeGasUsed": "394712", + "cumulativeGasUsed": "394816", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/ValidatorManagerFacet.json b/deployments/localhost/ValidatorManagerFacet.json deleted file mode 100644 index 76277f4..0000000 --- a/deployments/localhost/ValidatorManagerFacet.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "address": "0x2596c9892cD4c997e6cE22745a2eF8256b0B171f", - "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": "0xc22497865abee66601facd2755699e26e45f6e3735d65f1fed7a534c5a70b242", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "331464", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x0439cdc6779e6b8085c08a7e89a78163319a19acdb39de4a0ce341026e66304e", - "transactionHash": "0xc22497865abee66601facd2755699e26e45f6e3735d65f1fed7a534c5a70b242", - "logs": [], - "blockNumber": 26, - "cumulativeGasUsed": "331464", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4281d5d8e659c033492a4dfef522eed3", - "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(\\n address payable _sender\\n ) public view returns (uint256) {\\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(\\n uint256 _index\\n ) public view returns (uint256) {\\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\":\"0xbc65397b7e82c08279ce092d26b85d522994a16caae9fbd426e708d00b577bec\",\"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(\\n uint256 _numValidators\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (bool) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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(\\n ClaimsMask _claimsMask\\n ) internal pure returns (uint256) {\\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(\\n ClaimsMask _claimsMask,\\n uint256 _validatorIndex\\n ) internal pure returns (ClaimsMask) {\\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\":\"0x217eb2438f591832d5c61aaf7102c1dbc1feed4ddb871728fc98975ded0e72f2\",\"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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n address _validator\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 _value\\n ) internal {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal {\\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\":\"0x00f83789adb64fe2b18a7fa96c9f3e73043226bd8b3ec6887349ae4021d8e6ca\",\"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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\\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(\\n DiamondStorage storage ds,\\n address validator\\n ) internal {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (address payable) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (bool) {\\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(\\n DiamondStorage storage ds,\\n address sender\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds,\\n uint256 index\\n ) internal view returns (uint256) {\\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(\\n DiamondStorage storage ds\\n ) internal view returns (uint256) {\\n return ds.maxNumValidators;\\n }\\n}\\n\",\"keccak256\":\"0x14acffee6376e0ea2ca258c4ff60e9b29c162b2bcd11f2d5c3ad50698aebff2c\",\"license\":\"Apache-2.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610506806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638219fda41161005b5780638219fda4146100c2578063cc8a2451146100d7578063d2992f54146100ea578063f6023815146100f257600080fd5b8063101494ce146100825780631fcc449e1461009c57806355564a70146100af575b600080fd5b61008a6100fa565b60405190815260200160405180910390f35b61008a6100aa3660046103ff565b610139565b61008a6100bd3660046103ff565b61015b565b6000805160206104b18339815191525461008a565b61008a6100e536600461041c565b610176565b61008a610191565b61008a6101cb565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f81c5b91505090565b60006000805160206104b1833981519152610154818461020b565b9392505050565b60006000805160206104b183398151915261015481846102f5565b60006000805160206104b18339815191526101548184610367565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fe546000906000805160206104b183398151915290610133565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f01c60ff16610133565b60006001600160a01b0382166102545760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064015b60405180910390fd5b60005b60018401548110156102b05783600101818154811061027857610278610435565b6000918252602090912001546001600160a01b039081169084160361029e5790506102ef565b806102a881610461565b915050610257565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161024b565b92915050565b6000805b600184015481101561035d5783600101818154811061031a5761031a610435565b6000918252602090912001546001600160a01b039081169084160361034b576103438482610367565b9150506102ef565b8061035581610461565b9150506102f9565b5060009392505050565b600382015460009061015490836000600882106103bb5760405162461bcd60e51b8152602060048201526012602482015271696e646578206f7574206f662072616e676560701b604482015260640161024b565b60006103cc6001634000000061047a565b9050806103da84601e610491565b85901c1691505092915050565b6001600160a01b03811681146103fc57600080fd5b50565b60006020828403121561041157600080fd5b8135610154816103e7565b60006020828403121561042e57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016104735761047361044b565b5060010190565b60008282101561048c5761048c61044b565b500390565b60008160001904831182151516156104ab576104ab61044b565b50029056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fca2646970667358221220fd400eda940152213df247b2e985745ea7e642c73f890ac0824697ecd173f0da64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638219fda41161005b5780638219fda4146100c2578063cc8a2451146100d7578063d2992f54146100ea578063f6023815146100f257600080fd5b8063101494ce146100825780631fcc449e1461009c57806355564a70146100af575b600080fd5b61008a6100fa565b60405190815260200160405180910390f35b61008a6100aa3660046103ff565b610139565b61008a6100bd3660046103ff565b61015b565b6000805160206104b18339815191525461008a565b61008a6100e536600461041c565b610176565b61008a610191565b61008a6101cb565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f81c5b91505090565b60006000805160206104b1833981519152610154818461020b565b9392505050565b60006000805160206104b183398151915261015481846102f5565b60006000805160206104b18339815191526101548184610367565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fe546000906000805160206104b183398151915290610133565b7f8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1ff546000906000805160206104b18339815191529060f01c60ff16610133565b60006001600160a01b0382166102545760405162461bcd60e51b815260206004820152600960248201526806164647265737320360bc1b60448201526064015b60405180910390fd5b60005b60018401548110156102b05783600101818154811061027857610278610435565b6000918252602090912001546001600160a01b039081169084160361029e5790506102ef565b806102a881610461565b915050610257565b5060405162461bcd60e51b81526020600482015260136024820152721d985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161024b565b92915050565b6000805b600184015481101561035d5783600101818154811061031a5761031a610435565b6000918252602090912001546001600160a01b039081169084160361034b576103438482610367565b9150506102ef565b8061035581610461565b9150506102f9565b5060009392505050565b600382015460009061015490836000600882106103bb5760405162461bcd60e51b8152602060048201526012602482015271696e646578206f7574206f662072616e676560701b604482015260640161024b565b60006103cc6001634000000061047a565b9050806103da84601e610491565b85901c1691505092915050565b6001600160a01b03811681146103fc57600080fd5b50565b60006020828403121561041157600080fd5b8135610154816103e7565b60006020828403121561042e57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016104735761047361044b565b5060010190565b60008282101561048c5761048c61044b565b500390565b60008160001904831182151516156104ab576104ab61044b565b50029056fe8ab37fef2b2e34c4b62ff9948ee661cdcf34e209d7c20f4d1f6e83085e93b1fca2646970667358221220fd400eda940152213df247b2e985745ea7e642c73f890ac0824697ecd173f0da64736f6c634300080d0033", - "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/deployments/localhost/WorkerAuthManagerImpl.json b/deployments/localhost/WorkerAuthManagerImpl.json index bf4ae20..b6be2e6 100644 --- a/deployments/localhost/WorkerAuthManagerImpl.json +++ b/deployments/localhost/WorkerAuthManagerImpl.json @@ -142,19 +142,19 @@ "type": "function" } ], - "transactionHash": "0x25fc90131a26fac4ea3aa99f3a792efd26c8d28b852f98a0f237722d15759a3e", + "transactionHash": "0x17c44879b9399112dd56ef2160caac3e76ccd5ebc8c7514736574a37f52cea36", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", "transactionIndex": 0, - "gasUsed": "413820", + "gasUsed": "413926", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb229f8e28a061741fccf5ad7c49f087f4f4b487a548398865738b78460d2a162", - "transactionHash": "0x25fc90131a26fac4ea3aa99f3a792efd26c8d28b852f98a0f237722d15759a3e", + "blockHash": "0x612436b249aa9d99735517005e5570011ba49867d2aec7f35e53cb8e497c0245", + "transactionHash": "0x17c44879b9399112dd56ef2160caac3e76ccd5ebc8c7514736574a37f52cea36", "logs": [], "blockNumber": 4, - "cumulativeGasUsed": "413820", + "cumulativeGasUsed": "413926", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/WorkerManagerAuthManagerImpl.json b/deployments/localhost/WorkerManagerAuthManagerImpl.json index 0258d07..0f52ede 100644 --- a/deployments/localhost/WorkerManagerAuthManagerImpl.json +++ b/deployments/localhost/WorkerManagerAuthManagerImpl.json @@ -373,19 +373,19 @@ "type": "function" } ], - "transactionHash": "0x84c2cc404a54fde7aa515a1d4aa35b13c9c97ac64abacad8e8d9eb4e3aa1a99f", + "transactionHash": "0x2cd12df224e53610a005a0b2400f791b87090ff24c1d50a62bdc36518435e185", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", "transactionIndex": 0, - "gasUsed": "807618", + "gasUsed": "807840", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf56fde85b94b3ba08c0d80ab02181ccc3e0a75c010812c67f8b7b8cf503103da", - "transactionHash": "0x84c2cc404a54fde7aa515a1d4aa35b13c9c97ac64abacad8e8d9eb4e3aa1a99f", + "blockHash": "0xf003ad036a50cb07c86125befe2fa5c7cf0399f9cae39e3f62457d5bac3bf8f6", + "transactionHash": "0x2cd12df224e53610a005a0b2400f791b87090ff24c1d50a62bdc36518435e185", "logs": [], "blockNumber": 5, - "cumulativeGasUsed": "807618", + "cumulativeGasUsed": "807840", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/WorkerManagerImpl.json b/deployments/localhost/WorkerManagerImpl.json index dc9696a..f3541d6 100644 --- a/deployments/localhost/WorkerManagerImpl.json +++ b/deployments/localhost/WorkerManagerImpl.json @@ -245,19 +245,19 @@ "type": "function" } ], - "transactionHash": "0x3198564f4e3dc335f7ad743f1b3867b28cd789b0b49353ea56439428e0f5a010", + "transactionHash": "0x3f66e074b77dc743936e9ec4006cec6ca974ec5ab14172c993c0adf104fe5b38", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "transactionIndex": 0, - "gasUsed": "626414", + "gasUsed": "626582", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe25173bebdff5c8b922fdae679b4e74e787d3cc7c281a4fbc681b015070a2374", - "transactionHash": "0x3198564f4e3dc335f7ad743f1b3867b28cd789b0b49353ea56439428e0f5a010", + "blockHash": "0xddd68e7ad1c2923aa256ac30933c1459584c7562f184bbff48d1f82bac8f6360", + "transactionHash": "0x3f66e074b77dc743936e9ec4006cec6ca974ec5ab14172c993c0adf104fe5b38", "logs": [], "blockNumber": 3, - "cumulativeGasUsed": "626414", + "cumulativeGasUsed": "626582", "status": 1, "byzantium": true }, diff --git a/deployments/localhost/dapp.json b/deployments/localhost/dapp.json index ddc4588..c331755 100644 --- a/deployments/localhost/dapp.json +++ b/deployments/localhost/dapp.json @@ -1,6 +1,6 @@ { - "address": "0xF8C694fd58360De278d5fF2276B7130Bfdc0192A", - "blockHash": "0xee26f5870c2fdf30ab66e070df23b974916a5176fd1f2487b3df6a5d059ea325", - "blockNumber": 30, - "transactionHash": "0xb0457b62aa6a15d04451ebdfe315c25b92a40be1e5057813b47ee88e61a69264" + "address": "0x142105FC8dA71191b3a13C738Ba0cF4BC33325e2", + "blockHash": "0xa1dedaf2944315246f7e0256d7e2d1cebe788fac7d10f358d636411b838071f2", + "blockNumber": 22, + "transactionHash": "0xdb4398606faa9599ffa1f1356dacf5725b5cb243120b017318ab2f62fabeab4f" } \ No newline at end of file diff --git a/deployments/localhost/solcInputs/4281d5d8e659c033492a4dfef522eed3.json b/deployments/localhost/solcInputs/4281d5d8e659c033492a4dfef522eed3.json deleted file mode 100644 index 4a388ab..0000000 --- a/deployments/localhost/solcInputs/4281d5d8e659c033492a4dfef522eed3.json +++ /dev/null @@ -1,299 +0,0 @@ -{ - "language": "Solidity", - "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" - }, - "@cartesi/util/contracts/CartesiMathV2.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 CartesiMathV2 {\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 = n + 128;\n _num = _num >> 128;\n }\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) {\n n = n + 64;\n _num = _num >> 64;\n }\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) {\n n = n + 32;\n _num = _num >> 32;\n }\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) {\n n = n + 16;\n _num = _num >> 16;\n }\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) {\n n = n + 8;\n _num = _num >> 8;\n }\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) {\n n = n + 4;\n _num = _num >> 4;\n }\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) {\n n = n + 2;\n _num = _num >> 2;\n }\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) {\n n = n + 1;\n }\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 = n + 128;\n _num = _num << 128;\n }\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) {\n n = n + 64;\n _num = _num << 64;\n }\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 32;\n _num = _num << 32;\n }\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 16;\n _num = _num << 16;\n }\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 8;\n _num = _num << 8;\n }\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 4;\n _num = _num << 4;\n }\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 2;\n _num = _num << 2;\n }\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 1;\n }\n\n return n;\n }\n}\n" - }, - "@cartesi/util/contracts/MerkleV2.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 \"./CartesiMathV2.sol\";\n\nlibrary MerkleV2 {\n using CartesiMathV2 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 && _logSizeOfReplacement >= 3 && _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(siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement, \"Proof length does not match\");\n\n for (uint256 i; i < siblings.length; i++) {\n if ((_position & (size << i)) == 0) {\n _replacement = keccak256(abi.encodePacked(_replacement, siblings[i]));\n } else {\n _replacement = keccak256(abi.encodePacked(siblings[i], _replacement));\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) public pure returns (bytes32) {\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) public pure returns (bytes32) {\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(size << L_WORD_SIZE >= _data.length, \"data is bigger than drive\");\n // the stack depth is log2(_data.length / 8) + 2\n uint256 stack_depth = 2 + ((_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) public pure returns (bytes32) {\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) public pure returns (bytes32) {\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(abi.encodePacked(hashes[i], hashes[i + 1]));\n }\n\n return calculateRootFromPowerOfTwo(newHashes);\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 `from` to `to`.\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/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/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/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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: address zero is not a valid owner\");\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: invalid token ID\");\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 _requireMinted(tokenId);\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 token 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 _requireMinted(tokenId);\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: caller is not token 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: caller is not token 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 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 an {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 an {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 Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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 /// @solidity memory-safe-assembly\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/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/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 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/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\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/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/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" - }, - "@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (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 uint8 private constant _ADDRESS_LENGTH = 20;\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 /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "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/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/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(\n AppConfig calldata _appConfig\n ) public returns (CartesiDApp) {\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/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/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(\n address payable _sender,\n bytes32 _claim\n ) public returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) public returns (Result, bytes32[2] memory, address payable[2] memory) {\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(\n uint256 _validatorIndex\n ) public view returns (uint256) {\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/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/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(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\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(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n }\n\n // This implements ERC-165.\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n return ds.supportedInterfaces[_interfaceId];\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/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(\n bytes calldata _data\n ) public override returns (bool) {\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/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(\n bytes calldata _data\n ) public payable override returns (bytes32) {\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(\n bytes calldata _data\n ) public override returns (bool) {\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/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(\n address _validator\n ) public view override returns (uint256) {\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(\n address _validator\n ) public view override returns (uint256) {\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/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/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 {MerkleV2} from \"@cartesi/util/contracts/MerkleV2.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 validates notice\n /// @param _notice notice to be verified\n /// @param _v validity proof for this notice\n /// @return true if notice is valid\n function validateNotice(\n bytes calldata _notice,\n OutputValidityProof calldata _v\n ) public view override returns (bool) {\n LibOutput.DiamondStorage storage outputDS = LibOutput.diamondStorage();\n\n bytes memory encodedNotice = abi.encode(_notice);\n\n // reverts if validity proof doesnt match\n isValidNoticeProof(\n encodedNotice,\n outputDS.epochHashes[_v.epochIndex],\n _v\n );\n\n return true;\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 MerkleV2.getRootAfterReplacementInDrive(\n getIntraDrivePosition(_v.inputIndex, KECCAK_LOG2_SIZE),\n KECCAK_LOG2_SIZE,\n _outputEpochLog2Size,\n _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 = MerkleV2.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 MerkleV2.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(\n uint256 _index,\n uint256 _log2Size\n ) public pure returns (uint256) {\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" - }, - "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/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(\n address payable _sender\n ) public view returns (uint256) {\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(\n uint256 _index\n ) public view returns (uint256) {\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/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" - }, - "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(\n AppConfig calldata _appConfig\n ) external 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/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/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(\n address _facet\n ) external view 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(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\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/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/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/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(\n bytes calldata _data\n ) external payable 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/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(\n address _validator\n ) external view 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(\n address _validator\n ) external view 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/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 an input to the accumulating epoch's inbox\n /// @param _input bytes array of input\n /// @return hash of the input\n /// @dev There is a maximum size for the input data that is defined by the DApp\n function addInput(bytes calldata _input) external returns (bytes32);\n\n /// @notice Returns the hash of the input at the provided input index, for the current sealed epoch\n /// @param _index position of the input on inbox\n /// @return hash of the input\n function getInput(uint256 _index) external view returns (bytes32);\n\n /// @notice Returns the number of inputs on the current sealed epoch's inbox\n /// @return number of inputs of non active inbox\n function getNumberOfInputs() external view returns (uint256);\n\n /// @notice Returns the internal index of the current accumulating inbox\n /// @return index of current accumulating inbox\n function getCurrentInbox() external view returns (uint256);\n\n /// @notice Indicates that an input was added to the accumulating epoch's inbox\n /// @param epochNumber which epoch this input belongs to\n /// @param inputIndex index of the input just added\n /// @param sender msg.sender address\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/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/// @notice Data used to prove the validity of an output (notices and vouchers)\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 output metadata hashes of the related input\n/// @param vouchersEpochRootHash merkle root of all voucher metadata hashes of the related epoch\n/// @param noticesEpochRootHash merkle root of all notice metadata hashes of the related epoch\n/// @param machineStateHash hash of the machine state claimed for the related 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 a voucher\n /// @param _destination address of the target contract that will execute the payload\n /// @param _payload payload to be executed by the destination contract, containing a method signature and ABI-encoded parameters\n /// @param _v validity proof for the voucher\n /// @return true if voucher was executed successfully\n /// @dev vouchers can only be successfully executed one time, and only if the provided proof is valid\n function executeVoucher(\n address _destination,\n bytes calldata _payload,\n OutputValidityProof calldata _v\n ) external returns (bool);\n\n /// @notice Validates a notice\n /// @param _notice notice to be validated\n /// @param _v validity proof for the notice\n /// @return true if notice is valid\n function validateNotice(\n bytes calldata _notice,\n OutputValidityProof calldata _v\n ) external view 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 /// @notice Indicates that a voucher was executed\n /// @param voucherPosition voucher unique identifier considering epoch, input and output indices\n event VoucherExecuted(uint256 voucherPosition);\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/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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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(\n DiamondStorage storage ds\n ) internal view returns (address payable) {\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(\n DiamondStorage storage ds\n ) internal view returns (uint32) {\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(\n DiamondStorage storage ds,\n address sender\n ) internal view returns (bool) {\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(\n uint256 claimAgreementMask,\n uint256 consensusGoalMask\n ) internal pure returns (bool) {\n return claimAgreementMask == consensusGoalMask;\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(\n uint256 _numValidators\n ) internal pure returns (ClaimsMask) {\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(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) internal pure returns (uint256) {\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(\n ClaimsMask _claimsMask\n ) internal pure returns (ClaimsMask) {\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(\n ClaimsMask _claimsMask\n ) internal pure returns (uint256) {\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(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) internal pure returns (bool) {\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(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) internal pure returns (ClaimsMask) {\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(\n ClaimsMask _claimsMask\n ) internal pure returns (uint256) {\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(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) internal pure returns (ClaimsMask) {\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/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(\n address _init,\n bytes memory _calldata\n ) internal {\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/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/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(\n DiamondStorage storage ds,\n address _validator\n ) internal view returns (uint256) {\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(\n DiamondStorage storage ds,\n address _validator\n ) internal view returns (uint256) {\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(\n DiamondStorage storage ds,\n uint256 _value\n ) internal {\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(\n DiamondStorage storage ds,\n uint256 index\n ) internal {\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/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(\n DiamondStorage storage ds,\n uint256 index\n ) internal view returns (bytes32) {\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(\n DiamondStorage storage ds\n ) internal view returns (uint256) {\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(\n DiamondStorage storage ds,\n bytes memory input\n ) internal returns (bytes32) {\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(\n DiamondStorage storage ds,\n bytes memory input\n ) internal returns (bytes32) {\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/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(\n DiamondStorage storage ds\n ) internal view returns (uint256) {\n return ds.epochHashes.length;\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(\n DiamondStorage storage ds\n ) internal view returns (uint256) {\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/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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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 ) internal returns (Result, bytes32[2] memory, address payable[2] memory) {\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(\n DiamondStorage storage ds,\n address validator\n ) internal {\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(\n DiamondStorage storage ds\n ) internal view returns (bool) {\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(\n DiamondStorage storage ds\n ) internal view returns (address payable) {\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(\n DiamondStorage storage ds,\n address sender\n ) internal view returns (bool) {\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(\n DiamondStorage storage ds,\n address sender\n ) internal view returns (uint256) {\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(\n DiamondStorage storage ds,\n uint256 index\n ) internal view returns (uint256) {\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(\n DiamondStorage storage ds\n ) internal view returns (uint256) {\n return ds.maxNumValidators;\n }\n}\n" - }, - "contracts/test_helper/facets/DS1Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\n\ncontract DS1Facet {\n // Getters\n\n function getX() public view returns (uint32) {\n return LibDS1.diamondStorage().x;\n }\n\n function getY() public view returns (uint32) {\n return LibDS1.diamondStorage().y;\n }\n\n // Setters\n\n function setX(uint32 x) public {\n LibDS1.diamondStorage().x = x;\n }\n\n function setY(uint32 y) public {\n LibDS1.diamondStorage().y = y;\n }\n}\n" - }, - "contracts/test_helper/facets/DS2Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS2} from \"../libraries/LibDS2.sol\";\n\ncontract DS2Facet {\n // Getters\n\n function getX() public view returns (uint64) {\n return LibDS2.diamondStorage().x;\n }\n\n function getY() public view returns (uint32) {\n return LibDS2.diamondStorage().y;\n }\n\n // Setters\n\n function setX(uint64 x) public {\n LibDS2.diamondStorage().x = x;\n }\n\n function setY(uint32 y) public {\n LibDS2.diamondStorage().y = y;\n }\n}\n" - }, - "contracts/test_helper/facets/DS3Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS3} from \"../libraries/LibDS3.sol\";\n\ncontract DS3Facet {\n // Getters\n\n function getX() public view returns (uint32) {\n return LibDS3.diamondStorage().x;\n }\n\n function getY() public view returns (uint32) {\n return LibDS3.diamondStorage().y;\n }\n\n function getZ() public view returns (uint32) {\n return LibDS3.diamondStorage().z;\n }\n\n // Setters\n\n function setX(uint32 x) public {\n LibDS3.diamondStorage().x = x;\n }\n\n function setY(uint32 y) public {\n LibDS3.diamondStorage().y = y;\n }\n\n function setZ(uint32 z) public {\n LibDS3.diamondStorage().z = z;\n }\n}\n" - }, - "contracts/test_helper/facets/DS4Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS4} from \"../libraries/LibDS4.sol\";\n\ncontract DS4Facet {\n // Getters\n\n function getY() public view returns (uint32) {\n return LibDS4.diamondStorage().y;\n }\n\n // Setters\n\n function setY(uint32 y) public {\n LibDS4.diamondStorage().y = y;\n }\n}\n" - }, - "contracts/test_helper/facets/DS5Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS5} from \"../libraries/LibDS5.sol\";\n\ncontract DS5Facet {\n // Getters\n\n function getMappingEntry(uint256 key) public view returns (uint256) {\n return LibDS5.diamondStorage().map[key];\n }\n\n function getArrayLength() public view returns (uint256) {\n return LibDS5.diamondStorage().arr.length;\n }\n\n function getArrayElement(uint256 index) public view returns (uint256) {\n return LibDS5.diamondStorage().arr[index];\n }\n\n // Setters\n\n function setMappingEntry(uint256 key, uint256 value) public {\n LibDS5.diamondStorage().map[key] = value;\n }\n\n function addArrayElement(uint256 value) public {\n LibDS5.diamondStorage().arr.push(value);\n }\n}\n" - }, - "contracts/test_helper/facets/DS6Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS6} from \"../libraries/LibDS6.sol\";\n\ncontract DS6Facet {\n // Getters\n\n function getMappingEntry(uint256 key) public view returns (uint256) {\n return LibDS6.diamondStorage().map[key];\n }\n\n function getArrayLength() public view returns (uint256) {\n return LibDS6.diamondStorage().arr.length;\n }\n\n function getArrayElement(uint256 index) public view returns (uint256) {\n return LibDS6.diamondStorage().arr[index];\n }\n\n function getX() public view returns (uint256) {\n return LibDS6.diamondStorage().x;\n }\n\n // Setters\n\n function setMappingEntry(uint256 key, uint256 value) public {\n LibDS6.diamondStorage().map[key] = value;\n }\n\n function addArrayElement(uint256 value) public {\n LibDS6.diamondStorage().arr.push(value);\n }\n\n function setX(uint256 x) public {\n LibDS6.diamondStorage().x = x;\n }\n}\n" - }, - "contracts/test_helper/facets/DS7Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS7} from \"../libraries/LibDS7.sol\";\n\ncontract DS7Facet {\n // Getters\n\n function getMappingEntry(uint256 key) public view returns (uint256) {\n return LibDS7.diamondStorage().map[key];\n }\n\n function getArrayLength() public view returns (uint256) {\n return LibDS7.diamondStorage().arr.length;\n }\n\n function getArrayElement(uint256 index) public view returns (uint256) {\n return LibDS7.diamondStorage().arr[index];\n }\n\n function getX() public view returns (uint128) {\n return LibDS7.diamondStorage().x;\n }\n\n function getY() public view returns (uint128) {\n return LibDS7.diamondStorage().y;\n }\n\n // Setters\n\n function setMappingEntry(uint256 key, uint256 value) public {\n LibDS7.diamondStorage().map[key] = value;\n }\n\n function addArrayElement(uint256 value) public {\n LibDS7.diamondStorage().arr.push(value);\n }\n\n function setX(uint128 x) public {\n LibDS7.diamondStorage().x = x;\n }\n\n function setY(uint128 y) public {\n LibDS7.diamondStorage().y = y;\n }\n}\n" - }, - "contracts/test_helper/facets/DS8Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS8} from \"../libraries/LibDS8.sol\";\n\ncontract DS8Facet {\n // Getters\n\n function getX() public view returns (uint32) {\n return LibDS8.diamondStorage().x;\n }\n\n function getY() public view returns (uint32) {\n return LibDS8.diamondStorage().y;\n }\n\n function getArrayLength() public view returns (uint256) {\n return LibDS8.diamondStorage().arr.length;\n }\n\n function getArrayElement(uint256 index) public view returns (uint256) {\n return LibDS8.diamondStorage().arr[index];\n }\n\n function getMappingEntry(uint256 key) public view returns (uint256) {\n return LibDS8.diamondStorage().map[key];\n }\n\n // Setters\n\n function setX(uint32 x) public {\n LibDS8.diamondStorage().x = x;\n }\n\n function setY(uint32 y) public {\n LibDS8.diamondStorage().y = y;\n }\n\n function setMappingEntry(uint256 key, uint256 value) public {\n LibDS8.diamondStorage().map[key] = value;\n }\n\n function addArrayElement(uint256 value) public {\n LibDS8.diamondStorage().arr.push(value);\n }\n}\n" - }, - "contracts/test_helper/facets/DS9Facet.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\npragma solidity ^0.8.0;\n\nimport {LibDS9} from \"../libraries/LibDS9.sol\";\n\ncontract DS9Facet {\n // Getters\n\n function getX() public view returns (uint32) {\n return LibDS9.diamondStorage().x;\n }\n\n function getY() public view returns (uint32) {\n return LibDS9.diamondStorage().y;\n }\n\n function getArrayLength() public view returns (uint256) {\n return LibDS9.diamondStorage().arr.length;\n }\n\n function getArrayElement(uint256 index) public view returns (uint256) {\n return LibDS9.diamondStorage().arr[index];\n }\n\n function getMappingEntry(uint256 key) public view returns (uint256) {\n return LibDS9.diamondStorage().map[key];\n }\n\n // Setters\n\n function setX(uint32 x) public {\n LibDS9.diamondStorage().x = x;\n }\n\n function setY(uint32 y) public {\n LibDS9.diamondStorage().y = y;\n }\n\n function setMappingEntry(uint256 key, uint256 value) public {\n LibDS9.diamondStorage().map[key] = value;\n }\n\n function addArrayElement(uint256 value) public {\n LibDS9.diamondStorage().arr.push(value);\n }\n}\n" - }, - "contracts/test_helper/facets/Foo1Facet.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\npragma solidity ^0.8.0;\n\ncontract Foo1Facet {\n function foo() public pure returns (uint256) {\n return 42;\n }\n}\n" - }, - "contracts/test_helper/facets/Foo2Facet.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\npragma solidity ^0.8.0;\n\ncontract Foo2Facet {\n function foo() public pure returns (uint256) {\n return 10;\n }\n}\n" - }, - "contracts/test_helper/libraries/LibDS1.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\npragma solidity ^0.8.0;\n\nlibrary LibDS1 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds1.diamond.storage\");\n\n struct DiamondStorage {\n uint32 x;\n uint32 y;\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" - }, - "contracts/test_helper/libraries/LibDS2.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\npragma solidity ^0.8.0;\n\nlibrary LibDS2 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds2.diamond.storage\");\n\n struct DiamondStorage {\n uint64 x;\n uint32 y;\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" - }, - "contracts/test_helper/libraries/LibDS3.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\npragma solidity ^0.8.0;\n\nlibrary LibDS3 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds3.diamond.storage\");\n\n struct DiamondStorage {\n uint32 x;\n uint32 y;\n uint32 z;\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" - }, - "contracts/test_helper/libraries/LibDS4.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\npragma solidity ^0.8.0;\n\nlibrary LibDS4 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds4.diamond.storage\");\n\n struct DiamondStorage {\n uint32 y;\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" - }, - "contracts/test_helper/libraries/LibDS5.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\npragma solidity ^0.8.0;\n\nlibrary LibDS5 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds5.diamond.storage\");\n\n struct DiamondStorage {\n mapping(uint256 => uint256) map;\n uint256[] arr;\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" - }, - "contracts/test_helper/libraries/LibDS6.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\npragma solidity ^0.8.0;\n\nlibrary LibDS6 {\n // uses the same diamond storage as LibDS5\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds5.diamond.storage\");\n\n struct DiamondStorage {\n mapping(uint256 => uint256) map;\n uint256[] arr;\n uint256 x;\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" - }, - "contracts/test_helper/libraries/LibDS7.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\npragma solidity ^0.8.0;\n\nlibrary LibDS7 {\n // uses the same diamond storage as LibDS5\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds5.diamond.storage\");\n\n struct DiamondStorage {\n mapping(uint256 => uint256) map;\n uint256[] arr;\n uint128 x;\n uint128 y;\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" - }, - "contracts/test_helper/libraries/LibDS8.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\npragma solidity ^0.8.0;\n\nlibrary LibDS8 {\n // same as LibDS1\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds1.diamond.storage\");\n\n struct DiamondStorage {\n uint32 x;\n uint32 y;\n mapping(uint256 => uint256) map;\n uint256[] arr;\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" - }, - "contracts/test_helper/libraries/LibDS9.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\npragma solidity ^0.8.0;\n\nlibrary LibDS9 {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"ds9.diamond.storage\");\n\n struct DiamondStorage {\n uint32 x;\n uint32 y;\n mapping(uint256 => uint256) map;\n uint256[] arr;\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" - }, - "contracts/test_helper/SimpleContract.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 Contract test helper\npragma solidity ^0.8.0;\n\ncontract SimpleContract {\n function simple_function() public pure returns (string memory) {\n return \"from simple function\";\n }\n\n function simple_function(bytes32) public pure returns (string memory) {\n return \"from simple function with parameter\";\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" - }, - "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(\n uint256 _numValidators\n ) public pure returns (ClaimsMask) {\n return LibClaimsMask.newClaimsMaskWithConsensusGoalSet(_numValidators);\n }\n\n function getNumClaims(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) public pure returns (uint256) {\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(\n ClaimsMask _claimsMask\n ) public pure returns (ClaimsMask) {\n return LibClaimsMask.clearAgreementMask(_claimsMask);\n }\n\n function getAgreementMask(\n ClaimsMask _claimsMask\n ) public pure returns (uint256) {\n return LibClaimsMask.getAgreementMask(_claimsMask);\n }\n\n function alreadyClaimed(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) public pure returns (bool) {\n return LibClaimsMask.alreadyClaimed(_claimsMask, _validatorIndex);\n }\n\n function setAgreementMask(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) public pure returns (ClaimsMask) {\n return LibClaimsMask.setAgreementMask(_claimsMask, _validatorIndex);\n }\n\n function getConsensusGoalMask(\n ClaimsMask _claimsMask\n ) public pure returns (uint256) {\n return LibClaimsMask.getConsensusGoalMask(_claimsMask);\n }\n\n function removeValidator(\n ClaimsMask _claimsMask,\n uint256 _validatorIndex\n ) public pure returns (ClaimsMask) {\n return LibClaimsMask.removeValidator(_claimsMask, _validatorIndex);\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS1Init.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\n\ncontract DS1Init {\n function init(uint32 x, uint32 y) external {\n LibDS1.DiamondStorage storage ds = LibDS1.diamondStorage();\n ds.x = x;\n ds.y = y;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS2Upgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\nimport {LibDS2} from \"../libraries/LibDS2.sol\";\n\ncontract DS2Upgrade {\n function upgrade() external {\n LibDS1.DiamondStorage storage ds1 = LibDS1.diamondStorage();\n LibDS2.DiamondStorage storage ds2 = LibDS2.diamondStorage();\n ds2.x = uint64(ds1.x);\n ds2.y = ds1.y;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS3Upgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\nimport {LibDS3} from \"../libraries/LibDS3.sol\";\n\ncontract DS3Upgrade {\n function upgrade(uint32 z) external {\n LibDS1.DiamondStorage storage ds1 = LibDS1.diamondStorage();\n LibDS3.DiamondStorage storage ds3 = LibDS3.diamondStorage();\n ds3.x = ds1.x;\n ds3.y = ds1.y;\n ds3.z = z;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS4Upgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\nimport {LibDS4} from \"../libraries/LibDS4.sol\";\n\ncontract DS4Upgrade {\n function upgrade() external {\n LibDS1.DiamondStorage storage ds1 = LibDS1.diamondStorage();\n LibDS4.DiamondStorage storage ds4 = LibDS4.diamondStorage();\n ds4.y = ds1.y;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS6Downgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS6} from \"../libraries/LibDS6.sol\";\n\ncontract DS6Downgrade {\n function downgrade() external {\n LibDS6.DiamondStorage storage ds6 = LibDS6.diamondStorage();\n // we zero `x` because, if some upgrade occupies this slot,\n // it will have the default value. this could be fatal if\n // the variable that occupies the slot was an array.\n ds6.x = 0;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS6Init.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\npragma solidity ^0.8.0;\n\nimport {LibDS6} from \"../libraries/LibDS6.sol\";\n\ncontract DS6Init {\n function init(uint256 x) external {\n LibDS6.DiamondStorage storage ds = LibDS6.diamondStorage();\n ds.x = x;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS6Upgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS6} from \"../libraries/LibDS6.sol\";\n\ncontract DS6Upgrade {\n function upgrade(uint128 x) external {\n LibDS6.DiamondStorage storage ds6 = LibDS6.diamondStorage();\n ds6.x = x;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS7Downgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\nimport {LibDS7} from \"../libraries/LibDS7.sol\";\n\ncontract DS7Downgrade {\n function downgrade() external {\n LibDS1.DiamondStorage storage ds1 = LibDS1.diamondStorage();\n LibDS7.DiamondStorage storage ds7 = LibDS7.diamondStorage();\n ds1.x = uint32(ds7.x);\n ds1.y = uint32(ds7.y);\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS7Init.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\npragma solidity ^0.8.0;\n\nimport {LibDS7} from \"../libraries/LibDS7.sol\";\n\ncontract DS7Init {\n function init(uint128 x, uint128 y) external {\n LibDS7.DiamondStorage storage ds7 = LibDS7.diamondStorage();\n ds7.x = x;\n ds7.y = y;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS7Upgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS6} from \"../libraries/LibDS6.sol\";\nimport {LibDS7} from \"../libraries/LibDS7.sol\";\n\ncontract DS7Upgrade {\n function upgrade(uint128 y) external {\n LibDS6.DiamondStorage storage ds6 = LibDS6.diamondStorage();\n LibDS7.DiamondStorage storage ds7 = LibDS7.diamondStorage();\n ds7.x = uint128(ds6.x);\n ds7.y = y;\n }\n}\n" - }, - "contracts/test_helper/upgrade_initializers/DS9Upgrade.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\npragma solidity ^0.8.0;\n\nimport {LibDS1} from \"../libraries/LibDS1.sol\";\nimport {LibDS9} from \"../libraries/LibDS9.sol\";\n\ncontract DS9Upgrade {\n function upgrade() external {\n LibDS1.DiamondStorage storage ds1 = LibDS1.diamondStorage();\n LibDS9.DiamondStorage storage ds9 = LibDS9.diamondStorage();\n ds9.x = ds1.x;\n ds9.y = ds1.y;\n\n // just for debugging\n ds1.x = 0;\n ds1.y = 0;\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(\n address payable[] memory _validators\n ) private {\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" - } - }, - "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/deployments/localhost/solcInputs/ccf852a6f03ad282136085842817ac99.json b/deployments/localhost/solcInputs/ccf852a6f03ad282136085842817ac99.json new file mode 100644 index 0000000..0db3ccd --- /dev/null +++ b/deployments/localhost/solcInputs/ccf852a6f03ad282136085842817ac99.json @@ -0,0 +1,176 @@ +{ + "language": "Solidity", + "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" + }, + "@cartesi/util/contracts/CartesiMathV2.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 CartesiMathV2 {\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 = n + 128;\n _num = _num >> 128;\n }\n if (_num & 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF == 0) {\n n = n + 64;\n _num = _num >> 64;\n }\n if (_num & 0x00000000000000000000000000000000000000000000000000000000FFFFFFFF == 0) {\n n = n + 32;\n _num = _num >> 32;\n }\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000FFFF == 0) {\n n = n + 16;\n _num = _num >> 16;\n }\n if (_num & 0x00000000000000000000000000000000000000000000000000000000000000FF == 0) {\n n = n + 8;\n _num = _num >> 8;\n }\n if (_num & 0x000000000000000000000000000000000000000000000000000000000000000F == 0) {\n n = n + 4;\n _num = _num >> 4;\n }\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000003 == 0) {\n n = n + 2;\n _num = _num >> 2;\n }\n if (_num & 0x0000000000000000000000000000000000000000000000000000000000000001 == 0) {\n n = n + 1;\n }\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 = n + 128;\n _num = _num << 128;\n }\n if (_num & 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 == 0) {\n n = n + 64;\n _num = _num << 64;\n }\n if (_num & 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 32;\n _num = _num << 32;\n }\n if (_num & 0xFFFF000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 16;\n _num = _num << 16;\n }\n if (_num & 0xFF00000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 8;\n _num = _num << 8;\n }\n if (_num & 0xF000000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 4;\n _num = _num << 4;\n }\n if (_num & 0xC000000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 2;\n _num = _num << 2;\n }\n if (_num & 0x8000000000000000000000000000000000000000000000000000000000000000 == 0) {\n n = n + 1;\n }\n\n return n;\n }\n}\n" + }, + "@cartesi/util/contracts/MerkleV2.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 \"./CartesiMathV2.sol\";\n\nlibrary MerkleV2 {\n using CartesiMathV2 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 && _logSizeOfReplacement >= 3 && _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(siblings.length == _logSizeOfFullDrive - _logSizeOfReplacement, \"Proof length does not match\");\n\n for (uint256 i; i < siblings.length; i++) {\n if ((_position & (size << i)) == 0) {\n _replacement = keccak256(abi.encodePacked(_replacement, siblings[i]));\n } else {\n _replacement = keccak256(abi.encodePacked(siblings[i], _replacement));\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) public pure returns (bytes32) {\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) public pure returns (bytes32) {\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(size << L_WORD_SIZE >= _data.length, \"data is bigger than drive\");\n // the stack depth is log2(_data.length / 8) + 2\n uint256 stack_depth = 2 + ((_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) public pure returns (bytes32) {\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) public pure returns (bytes32) {\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(abi.encodePacked(hashes[i], hashes[i + 1]));\n }\n\n return calculateRootFromPowerOfTwo(newHashes);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n external\n view\n returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.\n *\n * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be\n * stuck.\n *\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\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/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\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/utils/ERC721Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\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/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/common/CanonicalMachine.sol": { + "content": "// Copyright 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.8;\n\n/// @title Canonical Machine Constants Library\n///\n/// @notice Defines several constants related to the reference implementation\n/// of the RISC-V machine that runs Linux, also known as the \"Cartesi Machine\".\nlibrary CanonicalMachine {\n /// @notice Base-2 logarithm of number of bytes.\n type Log2Size is uint64;\n\n /// @notice Machine word size (8 bytes).\n Log2Size constant WORD_LOG2_SIZE = Log2Size.wrap(3);\n\n /// @notice Machine address space size (2^64 bytes).\n Log2Size constant MACHINE_LOG2_SIZE = Log2Size.wrap(64);\n\n /// @notice Keccak-256 output size (32 bytes).\n Log2Size constant KECCAK_LOG2_SIZE = Log2Size.wrap(5);\n\n /// @notice Maximum input size (32 megabytes).\n Log2Size constant INPUT_MAX_LOG2_SIZE = Log2Size.wrap(25);\n\n /// @notice Maximum voucher metadata memory range (2 megabytes).\n Log2Size constant VOUCHER_METADATA_LOG2_SIZE = Log2Size.wrap(21);\n\n /// @notice Maximum notice metadata memory range (2 megabytes).\n Log2Size constant NOTICE_METADATA_LOG2_SIZE = Log2Size.wrap(21);\n\n /// @notice Maximum epoch voucher memory range (128 megabytes).\n Log2Size constant EPOCH_VOUCHER_LOG2_SIZE = Log2Size.wrap(37);\n\n /// @notice Maximum epoch notice memory range (128 megabytes).\n Log2Size constant EPOCH_NOTICE_LOG2_SIZE = Log2Size.wrap(37);\n\n /// @notice Unwrap `s` into its underlying uint64 value.\n /// @param s Base-2 logarithm of some number of bytes\n function uint64OfSize(Log2Size s) internal pure returns (uint64) {\n return Log2Size.unwrap(s);\n }\n\n /// @notice Return the position of an 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 Base-2 logarithm of intra memory range size\n function getIntraMemoryRangePosition(\n uint64 index,\n Log2Size log2Size\n ) internal pure returns (uint64) {\n return index << Log2Size.unwrap(log2Size);\n }\n}\n" + }, + "contracts/common/InputEncoding.sol": { + "content": "// Copyright 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.8;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/// @title Input Encoding Library\n\n/// @notice Defines the encoding of inputs added by core trustless and\n/// permissionless contracts, such as portals and relays.\nlibrary InputEncoding {\n /// @notice Encode an Ether deposit.\n /// @param sender The Ether sender\n /// @param value The amount of Ether being sent in Wei\n /// @param execLayerData Additional data to be interpreted by the execution layer\n /// @return The encoded input\n function encodeEtherDeposit(\n address sender,\n uint256 value,\n bytes calldata execLayerData\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n sender, // 20B\n value, // 32B\n execLayerData // arbitrary size\n );\n }\n\n /// @notice Encode an ERC-20 token deposit.\n /// @param ret The return value of `transferFrom`\n /// @param token The token contract\n /// @param sender The token sender\n /// @param amount The amount of tokens being sent\n /// @param execLayerData Additional data to be interpreted by the execution layer\n /// @return The encoded input\n function encodeERC20Deposit(\n bool ret,\n IERC20 token,\n address sender,\n uint256 amount,\n bytes calldata execLayerData\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n ret, // 1B\n token, // 20B\n sender, // 20B\n amount, // 32B\n execLayerData // arbitrary size\n );\n }\n\n /// @notice Encode an ERC-721 token deposit.\n /// @param token The token contract\n /// @param sender The token sender\n /// @param tokenId The token identifier\n /// @param baseLayerData Additional data to be interpreted by the base layer\n /// @param execLayerData Additional data to be interpreted by the execution layer\n /// @return The encoded input\n /// @dev `baseLayerData` should be forwarded to `token`.\n function encodeERC721Deposit(\n IERC721 token,\n address sender,\n uint256 tokenId,\n bytes calldata baseLayerData,\n bytes calldata execLayerData\n ) internal pure returns (bytes memory) {\n bytes memory data = abi.encode(baseLayerData, execLayerData);\n return\n abi.encodePacked(\n token, // 20B\n sender, // 20B\n tokenId, // 32B\n data // arbitrary size\n );\n }\n\n /// @notice Encode an ERC-1155 single token deposit.\n /// @param token The ERC-1155 token contract\n /// @param sender The token sender\n /// @param tokenId The identifier of the token being transferred\n /// @param value Transfer amount\n /// @param baseLayerData Additional data to be interpreted by the base layer\n /// @param execLayerData Additional data to be interpreted by the execution layer\n /// @return The encoded input\n /// @dev `baseLayerData` should be forwarded to `token`.\n function encodeSingleERC1155Deposit(\n IERC1155 token,\n address sender,\n uint256 tokenId,\n uint256 value,\n bytes calldata baseLayerData,\n bytes calldata execLayerData\n ) internal pure returns (bytes memory) {\n bytes memory data = abi.encode(baseLayerData, execLayerData);\n return\n abi.encodePacked(\n token, // 20B\n sender, // 20B\n tokenId, // 32B\n value, // 32B\n data // arbitrary size\n );\n }\n\n /// @notice Encode an ERC-1155 batch token deposit.\n /// @param token The ERC-1155 token contract\n /// @param sender The token sender\n /// @param tokenIds The identifiers of the tokens being transferred\n /// @param values Transfer amounts per token type\n /// @param baseLayerData Additional data to be interpreted by the base layer\n /// @param execLayerData Additional data to be interpreted by the execution layer\n /// @return The encoded input\n /// @dev `baseLayerData` should be forwarded to `token`.\n function encodeBatchERC1155Deposit(\n IERC1155 token,\n address sender,\n uint256[] calldata tokenIds,\n uint256[] calldata values,\n bytes calldata baseLayerData,\n bytes calldata execLayerData\n ) internal pure returns (bytes memory) {\n bytes memory data = abi.encode(\n tokenIds,\n values,\n baseLayerData,\n execLayerData\n );\n return\n abi.encodePacked(\n token, // 20B\n sender, // 20B\n data // arbitrary size\n );\n }\n\n /// @notice Encode a DApp address relay.\n /// @param dapp The DApp address\n /// @return The encoded input\n function encodeDAppAddressRelay(\n address dapp\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n dapp // 20B\n );\n }\n}\n" + }, + "contracts/common/OutputEncoding.sol": { + "content": "// Copyright 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.8;\n\n/// @title Output Encoding Library\n///\n/// @notice Defines the encoding of outputs generated by the off-chain machine.\nlibrary OutputEncoding {\n /// @notice Encode a notice.\n /// @param notice The notice\n /// @return The encoded output\n function encodeNotice(\n bytes calldata notice\n ) internal pure returns (bytes memory) {\n return abi.encode(notice);\n }\n\n /// @notice Encode a voucher.\n /// @param destination The address that will receive the payload through a message call\n /// @param payload The payload, which—in the case of Solidity contracts—encodes a function call\n /// @return The encoded output\n function encodeVoucher(\n address destination,\n bytes calldata payload\n ) internal pure returns (bytes memory) {\n return abi.encode(destination, payload);\n }\n}\n" + }, + "contracts/consensus/AbstractConsensus.sol": { + "content": "// Copyright 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.8;\n\nimport {IConsensus} from \"./IConsensus.sol\";\n\n/// @title Abstract Consensus\n/// @notice An abstract contract that partially implements `IConsensus`.\nabstract contract AbstractConsensus is IConsensus {\n /// @notice Emits an `ApplicationJoined` event with the message sender.\n function join() external override {\n emit ApplicationJoined(msg.sender);\n }\n}\n" + }, + "contracts/consensus/authority/Authority.sol": { + "content": "// Copyright 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.8;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {IConsensus} from \"../IConsensus.sol\";\nimport {AbstractConsensus} from \"../AbstractConsensus.sol\";\nimport {IInputBox} from \"../../inputs/IInputBox.sol\";\nimport {IHistory} from \"../../history/IHistory.sol\";\n\n/// @title Authority consensus\n/// @notice A consensus model controlled by a single address, the owner.\n/// Claims are stored in an auxiliary contract called `History`.\n/// @dev This contract inherits `AbstractConsensus` and OpenZeppelin's `Ownable` contract.\n/// For more information on `Ownable`, please consult OpenZeppelin's official documentation.\ncontract Authority is AbstractConsensus, Ownable {\n /// @notice The current history contract.\n /// @dev See the `getHistory` and `setHistory` functions.\n IHistory internal history;\n\n /// @notice The `Authority` contract was created.\n /// @param owner The address that initially owns the `Authority` contract\n /// @param inputBox The input box from which the authority fetches new inputs\n /// @dev MUST be triggered during construction.\n event ConsensusCreated(address owner, IInputBox inputBox);\n\n /// @notice A new history contract is used to store claims.\n /// @param history The new history contract\n /// @dev MUST be triggered on a successful call to `setHistory`.\n event NewHistory(IHistory history);\n\n /// @notice Constructs an `Authority` contract.\n /// @param _owner The initial contract owner\n /// @param _inputBox The input box contract\n /// @dev Emits a `ConsensusCreated` event.\n constructor(address _owner, IInputBox _inputBox) {\n // constructor in Ownable already called `transferOwnership(msg.sender)`, so\n // we only need to call `transferOwnership(_owner)` if _owner != msg.sender\n if (msg.sender != _owner) {\n transferOwnership(_owner);\n }\n emit ConsensusCreated(_owner, _inputBox);\n }\n\n /// @notice Submits a claim to the current history contract.\n /// The encoding of `_claimData` might vary depending on the\n /// implementation of the current history contract.\n /// @param _claimData Data for submitting a claim\n /// @dev Can only be called by the `Authority` owner,\n /// and the `Authority` contract must have ownership over\n /// its current history contract.\n function submitClaim(bytes calldata _claimData) external onlyOwner {\n history.submitClaim(_claimData);\n }\n\n /// @notice Transfer ownership over the current history contract to `_consensus`.\n /// @param _consensus The new owner of the current history contract\n /// @dev Can only be called by the `Authority` owner,\n /// and the `Authority` contract must have ownership over\n /// its current history contract.\n function migrateHistoryToConsensus(address _consensus) external onlyOwner {\n history.migrateToConsensus(_consensus);\n }\n\n /// @notice Make `Authority` point to another history contract.\n /// @param _history The new history contract\n /// @dev Emits a `NewHistory` event.\n /// Can only be called by the `Authority` owner.\n function setHistory(IHistory _history) external onlyOwner {\n history = _history;\n emit NewHistory(_history);\n }\n\n /// @notice Get the current history contract.\n /// @return The current history contract\n function getHistory() external view returns (IHistory) {\n return history;\n }\n\n /// @notice Get a claim from the current history.\n /// The encoding of `_proofContext` might vary depending on the\n /// implementation of the current history contract.\n /// @inheritdoc IConsensus\n function getClaim(\n address _dapp,\n bytes calldata _proofContext\n ) external view override returns (bytes32, uint256, uint256) {\n return history.getClaim(_dapp, _proofContext);\n }\n\n /// @notice Transfer some amount of ERC-20 tokens to a recipient.\n /// @param _token The token contract\n /// @param _recipient The recipient address\n /// @param _amount The amount of tokens to be withdrawn\n /// @dev Can only be called by the `Authority` owner.\n function withdrawERC20Tokens(\n IERC20 _token,\n address _recipient,\n uint256 _amount\n ) external onlyOwner {\n require(\n _token.transfer(_recipient, _amount),\n \"Authority: withdrawal failed\"\n );\n }\n}\n" + }, + "contracts/consensus/IConsensus.sol": { + "content": "// Copyright 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.8;\n\n/// @title Consensus interface\n///\n/// @notice This contract defines a generic interface for consensuses.\n/// We use the word \"consensus\" to designate a contract that provides claims\n/// in the base layer regarding the state of off-chain machines running in\n/// the execution layer. How this contract is able to reach consensus, who is\n/// able to submit claims, and how are claims stored in the base layer are\n/// some of the implementation details left unspecified by this interface.\n///\n/// From the point of view of a DApp, these claims are necessary to validate\n/// on-chain action allowed by the off-chain machine in the form of vouchers\n/// and notices. Each claim is composed of three parts: an epoch hash, a first\n/// index, and a last index. We'll explain each of these parts below.\n///\n/// First, let us define the word \"epoch\". For finality reasons, we need to\n/// divide the stream of inputs being fed into the off-chain machine into\n/// batches of inputs, which we call \"epoches\". At the end of every epoch,\n/// we summarize the state of the off-chain machine in a single hash, called\n/// \"epoch hash\". Please note that this interface does not define how this\n/// stream of inputs is being chopped up into epoches.\n///\n/// The other two parts are simply the indices of the first and last inputs\n/// accepted during the epoch. Logically, the first index MUST BE less than\n/// or equal to the last index. As a result, every epoch MUST accept at least\n/// one input. This assumption stems from the fact that the state of a machine\n/// can only change after an input is fed into it.\n///\n/// Examples of possible implementations of this interface include:\n///\n/// * An authority consensus, controlled by a single address who has full\n/// control over epoch boundaries, claim submission, asset management, etc.\n///\n/// * A quorum consensus, controlled by a limited set of validators, that\n/// vote on the state of the machine at the end of every epoch. Also, epoch\n/// boundaries are determined by the timestamp in the base layer, and assets\n/// are split equally amongst the validators.\n///\n/// * An NxN consensus, which allows anyone to submit and dispute claims\n/// in the base layer. Epoch boundaries are determined in the same fashion\n/// as in the quorum example.\n///\ninterface IConsensus {\n /// @notice An application has joined the consensus' validation set.\n /// @param application The application\n /// @dev MUST be triggered on a successful call to `join`.\n event ApplicationJoined(address application);\n\n /// @notice Get a specific claim regarding a specific DApp.\n /// The encoding of `_proofContext` might vary\n /// depending on the implementation.\n /// @param _dapp The DApp address\n /// @param _proofContext Data for retrieving the desired claim\n /// @return epochHash_ The claimed epoch hash\n /// @return firstInputIndex_ The index of the first input of the epoch in the input box\n /// @return lastInputIndex_ The index of the last input of the epoch in the input box\n function getClaim(\n address _dapp,\n bytes calldata _proofContext\n )\n external\n view\n returns (\n bytes32 epochHash_,\n uint256 firstInputIndex_,\n uint256 lastInputIndex_\n );\n\n /// @notice Signal the consensus that the message sender wants to join its validation set.\n /// @dev MUST fire an `ApplicationJoined` event with the message sender as argument.\n function join() external;\n}\n" + }, + "contracts/dapp/CartesiDApp.sol": { + "content": "// Copyright 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.8;\n\nimport {ICartesiDApp, Proof} from \"./ICartesiDApp.sol\";\nimport {IConsensus} from \"../consensus/IConsensus.sol\";\nimport {LibOutputValidation, OutputValidityProof} from \"../library/LibOutputValidation.sol\";\nimport {Bitmask} from \"@cartesi/util/contracts/Bitmask.sol\";\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\nimport {ERC1155Holder} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\n/// @title Cartesi DApp\n///\n/// @notice This contract acts as the base layer incarnation of a DApp running on the execution layer.\n/// The DApp is hereby able to interact with other smart contracts through the execution of vouchers\n/// and the validation of notices. These outputs are generated by the DApp backend on the execution\n/// layer and can be proven in the base layer thanks to claims submitted by a consensus contract.\n///\n/// A voucher is a one-time message call to another contract. It can encode asset transfers, approvals,\n/// or any other message call that doesn't require Ether to be sent along. A voucher will only be consumed\n/// if the underlying message call succeeds (that is, it doesn't revert). Furthermore, the return data of\n/// the message call is discarded entirely. As a protective measure against reentrancy attacks, nested\n/// voucher executions are prohibited.\n///\n/// A notice, on the other hand, constitutes an arbitrary piece of data that can be proven any number of times.\n/// On their own, they do not trigger any type of contract-to-contract interaction.\n/// Rather, they merely serve to attest off-chain results, e.g. which player won a particular chess match.\n///\n/// Every DApp is subscribed to a consensus contract, and governed by a single address, the owner.\n/// The consensus has the power of submitting claims, which, in turn, are used to validate vouchers and notices.\n/// Meanwhile, the owner has complete power over the DApp, as it can replace the consensus at any time.\n/// Therefore, the users of a DApp must trust both the consensus and the DApp owner.\n///\n/// The DApp developer can choose whichever ownership and consensus models it wants.\n///\n/// Examples of DApp ownership models include:\n///\n/// * no owner (address zero)\n/// * individual signer (externally-owned account)\n/// * multiple signers (multi-sig)\n/// * DAO (decentralized autonomous organization)\n/// * self-owned DApp (off-chain governance logic)\n///\n/// See `IConsensus` for examples of consensus models.\n///\n/// This contract inherits the following OpenZeppelin contracts.\n/// For more information, please consult OpenZeppelin's official documentation.\n///\n/// * `Ownable`\n/// * `ERC721Holder`\n/// * `ERC1155Holder`\n/// * `ReentrancyGuard`\n///\ncontract CartesiDApp is\n ICartesiDApp,\n Ownable,\n ERC721Holder,\n ERC1155Holder,\n ReentrancyGuard\n{\n using Bitmask for mapping(uint256 => uint256);\n using LibOutputValidation for OutputValidityProof;\n\n /// @notice The initial machine state hash.\n /// @dev See the `getTemplateHash` function.\n bytes32 internal immutable templateHash;\n\n /// @notice The executed voucher bitmask, which keeps track of which vouchers\n /// were executed already in order to avoid re-execution.\n /// @dev See the `wasVoucherExecuted` function.\n mapping(uint256 => uint256) internal voucherBitmask;\n\n /// @notice The current consensus contract.\n /// @dev See the `getConsensus` and `migrateToConsensus` functions.\n IConsensus internal consensus;\n\n /// @notice Creates a `CartesiDApp` contract.\n /// @param _consensus The initial consensus contract\n /// @param _owner The initial DApp owner\n /// @param _templateHash The initial machine state hash\n /// @dev Calls the `join` function on `_consensus`.\n constructor(IConsensus _consensus, address _owner, bytes32 _templateHash) {\n transferOwnership(_owner);\n templateHash = _templateHash;\n consensus = _consensus;\n\n _consensus.join();\n }\n\n function executeVoucher(\n address _destination,\n bytes calldata _payload,\n Proof calldata _proof\n ) external override nonReentrant returns (bool) {\n bytes32 epochHash;\n uint256 firstInputIndex;\n uint256 lastInputIndex;\n uint256 inboxInputIndex;\n\n // query the current consensus for the desired claim\n (epochHash, firstInputIndex, lastInputIndex) = getClaim(_proof.context);\n\n // validate the epoch input index and calculate the inbox input index\n // based on the input index range provided by the consensus\n inboxInputIndex = _proof.validity.validateInputIndexRange(\n firstInputIndex,\n lastInputIndex\n );\n\n // reverts if proof isn't valid\n _proof.validity.validateVoucher(_destination, _payload, epochHash);\n\n uint256 voucherPosition = LibOutputValidation.getBitMaskPosition(\n _proof.validity.outputIndex,\n inboxInputIndex\n );\n\n // check if voucher has been executed\n require(\n !_wasVoucherExecuted(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 voucherBitmask.setBit(voucherPosition, true);\n emit VoucherExecuted(voucherPosition);\n }\n\n return succ;\n }\n\n function wasVoucherExecuted(\n uint256 _inboxInputIndex,\n uint256 _outputIndex\n ) external view override returns (bool) {\n uint256 voucherPosition = LibOutputValidation.getBitMaskPosition(\n _outputIndex,\n _inboxInputIndex\n );\n return _wasVoucherExecuted(voucherPosition);\n }\n\n function _wasVoucherExecuted(\n uint256 _voucherPosition\n ) internal view returns (bool) {\n return voucherBitmask.getBit(_voucherPosition);\n }\n\n function validateNotice(\n bytes calldata _notice,\n Proof calldata _proof\n ) external view override returns (bool) {\n bytes32 epochHash;\n uint256 firstInputIndex;\n uint256 lastInputIndex;\n\n // query the current consensus for the desired claim\n (epochHash, firstInputIndex, lastInputIndex) = getClaim(_proof.context);\n\n // validate the epoch input index based on the input index range\n // provided by the consensus\n _proof.validity.validateInputIndexRange(\n firstInputIndex,\n lastInputIndex\n );\n\n // reverts if proof isn't valid\n _proof.validity.validateNotice(_notice, epochHash);\n\n return true;\n }\n\n /// @notice Retrieve a claim about the DApp from the current consensus.\n /// The encoding of `_proofContext` might vary depending on the implementation.\n /// @param _proofContext Data for retrieving the desired claim\n /// @return The claimed epoch hash\n /// @return The index of the first input of the epoch in the input box\n /// @return The index of the last input of the epoch in the input box\n function getClaim(\n bytes calldata _proofContext\n ) internal view returns (bytes32, uint256, uint256) {\n return consensus.getClaim(address(this), _proofContext);\n }\n\n function migrateToConsensus(\n IConsensus _newConsensus\n ) external override onlyOwner {\n consensus = _newConsensus;\n\n _newConsensus.join();\n\n emit NewConsensus(_newConsensus);\n }\n\n function getTemplateHash() external view override returns (bytes32) {\n return templateHash;\n }\n\n function getConsensus() external view override returns (IConsensus) {\n return consensus;\n }\n\n /// @notice Accept Ether transfers.\n /// @dev If you wish to transfer Ether to a DApp while informing\n /// the DApp backend of it, then please do so through the Ether portal contract.\n receive() external payable {}\n\n /// @notice Transfer some amount of Ether to some recipient.\n /// @param _receiver The address which will receive the amount of Ether\n /// @param _value The amount of Ether to be transferred in Wei\n /// @dev This function can only be called by the DApp itself through vouchers.\n function withdrawEther(address _receiver, uint256 _value) external {\n require(msg.sender == address(this), \"only itself\");\n (bool sent, ) = _receiver.call{value: _value}(\"\");\n require(sent, \"withdrawEther failed\");\n }\n}\n" + }, + "contracts/dapp/CartesiDAppFactory.sol": { + "content": "// Copyright 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.8;\n\nimport {ICartesiDAppFactory} from \"./ICartesiDAppFactory.sol\";\nimport {IConsensus} from \"../consensus/IConsensus.sol\";\nimport {CartesiDApp} from \"./CartesiDApp.sol\";\n\n/// @title Cartesi DApp Factory\n/// @notice Allows anyone to reliably deploy a new `CartesiDApp` contract.\ncontract CartesiDAppFactory is ICartesiDAppFactory {\n function newApplication(\n IConsensus _consensus,\n address _dappOwner,\n bytes32 _templateHash\n ) external override returns (CartesiDApp) {\n CartesiDApp application = new CartesiDApp(\n _consensus,\n _dappOwner,\n _templateHash\n );\n\n emit ApplicationCreated(\n _consensus,\n _dappOwner,\n _templateHash,\n application\n );\n\n return application;\n }\n\n function newApplication(\n IConsensus _consensus,\n address _dappOwner,\n bytes32 _templateHash,\n bytes32 _salt\n ) external override returns (CartesiDApp) {\n CartesiDApp application = new CartesiDApp{salt: _salt}(\n _consensus,\n _dappOwner,\n _templateHash\n );\n\n emit ApplicationCreated(\n _consensus,\n _dappOwner,\n _templateHash,\n application\n );\n\n return application;\n }\n\n function calculateApplicationAddress(\n IConsensus _consensus,\n address _dappOwner,\n bytes32 _templateHash,\n bytes32 _salt\n ) external view override returns (address) {\n return\n address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(\n abi.encodePacked(\n type(CartesiDApp).creationCode,\n abi.encode(\n _consensus,\n _dappOwner,\n _templateHash\n )\n )\n )\n )\n )\n )\n )\n );\n }\n}\n" + }, + "contracts/dapp/ICartesiDApp.sol": { + "content": "// Copyright 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.8;\n\nimport {IConsensus} from \"../consensus/IConsensus.sol\";\nimport {OutputValidityProof} from \"../library/LibOutputValidation.sol\";\n\n/// @notice Data for validating outputs.\n/// @param validity A validity proof for the output\n/// @param context Data for querying the right claim from the current consensus contract\n/// @dev The encoding of `context` might vary depending on the implementation of the consensus contract.\nstruct Proof {\n OutputValidityProof validity;\n bytes context;\n}\n\n/// @title Cartesi DApp interface\ninterface ICartesiDApp {\n // Events\n\n /// @notice The DApp has migrated to another consensus contract.\n /// @param newConsensus The new consensus contract\n /// @dev MUST be triggered on a successful call to `migrateToConsensus`.\n event NewConsensus(IConsensus newConsensus);\n\n /// @notice A voucher was executed from the DApp.\n /// @param voucherId A number that uniquely identifies the voucher\n /// amongst all vouchers emitted by this DApp\n event VoucherExecuted(uint256 voucherId);\n\n // Permissioned functions\n\n /// @notice Migrate the DApp to a new consensus.\n /// @param _newConsensus The new consensus\n /// @dev Can only be called by the DApp owner.\n function migrateToConsensus(IConsensus _newConsensus) external;\n\n // Permissionless functions\n\n /// @notice Try to execute a voucher.\n ///\n /// Reverts if voucher was already successfully executed.\n ///\n /// @param _destination The address that will receive the payload through a message call\n /// @param _payload The payload, which—in the case of Solidity contracts—encodes a function call\n /// @param _proof The proof used to validate the voucher against\n /// a claim submitted by the current consensus contract\n /// @return Whether the execution was successful or not\n /// @dev On a successful execution, emits a `VoucherExecuted` event.\n function executeVoucher(\n address _destination,\n bytes calldata _payload,\n Proof calldata _proof\n ) external returns (bool);\n\n /// @notice Check whether a voucher has been executed.\n /// @param _inboxInputIndex The index of the input in the input box\n /// @param _outputIndex The index of output emitted by the input\n /// @return Whether the voucher has been executed before\n function wasVoucherExecuted(\n uint256 _inboxInputIndex,\n uint256 _outputIndex\n ) external view returns (bool);\n\n /// @notice Validate a notice.\n /// @param _notice The notice\n /// @param _proof Data for validating outputs\n /// @return Whether the notice is valid or not\n function validateNotice(\n bytes calldata _notice,\n Proof calldata _proof\n ) external view returns (bool);\n\n /// @notice Get the DApp's template hash.\n /// @return The DApp's template hash\n function getTemplateHash() external view returns (bytes32);\n\n /// @notice Get the current consensus.\n /// @return The current consensus\n function getConsensus() external view returns (IConsensus);\n}\n" + }, + "contracts/dapp/ICartesiDAppFactory.sol": { + "content": "// Copyright 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.8;\n\nimport {CartesiDApp} from \"./CartesiDApp.sol\";\nimport {IConsensus} from \"../consensus/IConsensus.sol\";\n\n/// @title Cartesi DApp Factory interface\ninterface ICartesiDAppFactory {\n // Events\n\n /// @notice A new application was deployed.\n /// @param consensus The initial consensus contract\n /// @param dappOwner The initial DApp owner\n /// @param templateHash The initial machine state hash\n /// @param application The application\n /// @dev MUST be triggered on a successful call to `newApplication`.\n event ApplicationCreated(\n IConsensus indexed consensus,\n address dappOwner,\n bytes32 templateHash,\n CartesiDApp application\n );\n\n // Permissionless functions\n\n /// @notice Deploy a new application.\n /// @param _consensus The initial consensus contract\n /// @param _dappOwner The initial DApp owner\n /// @param _templateHash The initial machine state hash\n /// @return The application\n /// @dev On success, MUST emit an `ApplicationCreated` event.\n function newApplication(\n IConsensus _consensus,\n address _dappOwner,\n bytes32 _templateHash\n ) external returns (CartesiDApp);\n\n /// @notice Deploy a new application deterministically.\n /// @param _consensus The initial consensus contract\n /// @param _dappOwner The initial DApp owner\n /// @param _templateHash The initial machine state hash\n /// @param _salt The salt used to deterministically generate the DApp address\n /// @return The application\n /// @dev On success, MUST emit an `ApplicationCreated` event.\n function newApplication(\n IConsensus _consensus,\n address _dappOwner,\n bytes32 _templateHash,\n bytes32 _salt\n ) external returns (CartesiDApp);\n\n /// @notice Calculate the address of an application to be deployed deterministically.\n /// @param _consensus The initial consensus contract\n /// @param _dappOwner The initial DApp owner\n /// @param _templateHash The initial machine state hash\n /// @param _salt The salt used to deterministically generate the DApp address\n /// @return The deterministic application address\n /// @dev Beware that only the `newApplication` function with the `_salt` parameter\n /// is able to deterministically deploy an application.\n function calculateApplicationAddress(\n IConsensus _consensus,\n address _dappOwner,\n bytes32 _templateHash,\n bytes32 _salt\n ) external view returns (address);\n}\n" + }, + "contracts/history/History.sol": { + "content": "// Copyright 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.8;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport {IHistory} from \"./IHistory.sol\";\n\n/// @title Simple History\n///\n/// @notice This contract stores claims for each DApp individually.\n/// This means that, for each DApp, the contract stores an array of\n/// `Claim` entries, where each `Claim` is composed of:\n///\n/// * An epoch hash (`bytes32`)\n/// * A closed interval of input indices (`uint128`, `uint128`)\n///\n/// The contract guarantees that the first interval starts at index 0,\n/// and that the following intervals don't have gaps or overlaps.\n///\n/// Furthermore, claims can only be submitted by the contract owner\n/// through `submitClaim`, but can be retrieved by anyone with `getClaim`.\n///\n/// @dev This contract inherits OpenZeppelin's `Ownable` contract.\n/// For more information on `Ownable`, please consult OpenZeppelin's official documentation.\ncontract History is IHistory, Ownable {\n struct Claim {\n bytes32 epochHash;\n uint128 firstIndex;\n uint128 lastIndex;\n }\n\n /// @notice Mapping from DApp address to array of claims.\n /// @dev See the `getClaim` and `submitClaim` functions.\n mapping(address => Claim[]) internal claims;\n\n /// @notice A new claim regarding a specific DApp was submitted.\n /// @param dapp The address of the DApp\n /// @param claim The newly-submitted claim\n /// @dev MUST be triggered on a successful call to `submitClaim`.\n event NewClaimToHistory(address indexed dapp, Claim claim);\n\n /// @notice Creates a `History` contract.\n /// @param _owner The initial owner\n constructor(address _owner) {\n // constructor in Ownable already called `transferOwnership(msg.sender)`, so\n // we only need to call `transferOwnership(_owner)` if _owner != msg.sender\n if (_owner != msg.sender) {\n transferOwnership(_owner);\n }\n }\n\n /// @notice Submit a claim regarding a DApp.\n /// There are several requirements for this function to be called successfully.\n ///\n /// * `_claimData` MUST be well-encoded. In Solidity, it can be constructed\n /// as `abi.encode(dapp, claim)`, where `dapp` is the DApp address (type `address`)\n /// and `claim` is the claim structure (type `Claim`).\n ///\n /// * `firstIndex` MUST be less than or equal to `lastIndex`.\n /// As a result, every claim MUST encompass AT LEAST one input.\n ///\n /// * If this is the DApp's first claim, then `firstIndex` MUST be `0`.\n /// Otherwise, `firstIndex` MUST be the `lastClaim.lastIndex + 1`.\n /// In other words, claims MUST NOT skip inputs.\n ///\n /// @inheritdoc IHistory\n /// @dev Emits a `NewClaimToHistory` event. Should have access control.\n function submitClaim(\n bytes calldata _claimData\n ) external override onlyOwner {\n (address dapp, Claim memory claim) = abi.decode(\n _claimData,\n (address, Claim)\n );\n\n require(claim.firstIndex <= claim.lastIndex, \"History: FI > LI\");\n\n Claim[] storage dappClaims = claims[dapp];\n uint256 numDAppClaims = dappClaims.length;\n\n require(\n claim.firstIndex ==\n (\n (numDAppClaims == 0)\n ? 0\n : (dappClaims[numDAppClaims - 1].lastIndex + 1)\n ),\n \"History: unclaimed inputs\"\n );\n\n dappClaims.push(claim);\n\n emit NewClaimToHistory(dapp, claim);\n }\n\n /// @notice Get a specific claim regarding a specific DApp.\n /// There are several requirements for this function to be called successfully.\n ///\n /// * `_proofContext` MUST be well-encoded. In Solidity, it can be constructed\n /// as `abi.encode(claimIndex)`, where `claimIndex` is the claim index (type `uint256`).\n ///\n /// * `claimIndex` MUST be inside the interval `[0, n)` where `n` is the number of claims\n /// that have been submitted to `_dapp` already.\n ///\n /// @inheritdoc IHistory\n function getClaim(\n address _dapp,\n bytes calldata _proofContext\n ) external view override returns (bytes32, uint256, uint256) {\n uint256 claimIndex = abi.decode(_proofContext, (uint256));\n\n Claim memory claim = claims[_dapp][claimIndex];\n\n return (claim.epochHash, claim.firstIndex, claim.lastIndex);\n }\n\n /// @inheritdoc IHistory\n /// @dev Emits an `OwnershipTransferred` event. Should have access control.\n function migrateToConsensus(\n address _consensus\n ) external override onlyOwner {\n transferOwnership(_consensus);\n }\n}\n" + }, + "contracts/history/IHistory.sol": { + "content": "// Copyright 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.8;\n\n/// @title History interface\ninterface IHistory {\n // Permissioned functions\n\n /// @notice Submit a claim.\n /// The encoding of `_claimData` might vary\n /// depending on the history implementation.\n /// @param _claimData Data for submitting a claim\n /// @dev Should have access control.\n function submitClaim(bytes calldata _claimData) external;\n\n /// @notice Transfer ownership to another consensus.\n /// @param _consensus The new consensus\n /// @dev Should have access control.\n function migrateToConsensus(address _consensus) external;\n\n // Permissionless functions\n\n /// @notice Get a specific claim regarding a specific DApp.\n /// The encoding of `_proofContext` might vary\n /// depending on the history implementation.\n /// @param _dapp The DApp address\n /// @param _proofContext Data for retrieving the desired claim\n /// @return epochHash_ The claimed epoch hash\n /// @return firstInputIndex_ The index of the first input of the epoch in the input box\n /// @return lastInputIndex_ The index of the last input of the epoch in the input box\n function getClaim(\n address _dapp,\n bytes calldata _proofContext\n )\n external\n view\n returns (\n bytes32 epochHash_,\n uint256 firstInputIndex_,\n uint256 lastInputIndex_\n );\n}\n" + }, + "contracts/inputs/IInputBox.sol": { + "content": "// Copyright 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.8;\n\n/// @title Input Box interface\ninterface IInputBox {\n /// @notice Emitted when an input is added to a DApp's input box.\n /// @param dapp The address of the DApp\n /// @param inboxInputIndex The index of the input in the input box\n /// @param sender The address that sent the input\n /// @param input The contents of the input\n /// @dev MUST be triggered on a successful call to `addInput`.\n event InputAdded(\n address indexed dapp,\n uint256 indexed inboxInputIndex,\n address sender,\n bytes input\n );\n\n /// @notice Add an input to a DApp's input box.\n /// @param _dapp The address of the DApp\n /// @param _input The contents of the input\n /// @return The hash of the input plus some extra metadata\n /// @dev MUST fire an `InputAdded` event accordingly.\n function addInput(\n address _dapp,\n bytes calldata _input\n ) external returns (bytes32);\n\n /// @notice Get the number of inputs in a DApp's input box.\n /// @param _dapp The address of the DApp\n /// @return Number of inputs in the DApp's input box\n function getNumberOfInputs(address _dapp) external view returns (uint256);\n\n /// @notice Get the hash of an input in a DApp's input box.\n /// @param _dapp The address of the DApp\n /// @param _index The index of the input in the DApp's input box\n /// @return The hash of the input at the provided index in the DApp's input box\n /// @dev `_index` MUST be in the interval `[0,n)` where `n` is the number of\n /// inputs in the DApp's input box. See the `getNumberOfInputs` function.\n function getInputHash(\n address _dapp,\n uint256 _index\n ) external view returns (bytes32);\n}\n" + }, + "contracts/inputs/InputBox.sol": { + "content": "// Copyright 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.8;\n\nimport {IInputBox} from \"./IInputBox.sol\";\nimport {LibInput} from \"../library/LibInput.sol\";\n\n/// @title Input Box\n///\n/// @notice Trustless and permissionless contract that receives arbitrary blobs\n/// (called \"inputs\") from anyone and adds a compound hash to an append-only list\n/// (called \"input box\"). Each DApp has its own input box.\n///\n/// The hash that is stored on-chain is composed by the hash of the input blob,\n/// the block number and timestamp, the input sender address, and the input index.\n///\n/// Data availability is guaranteed by the emission of `InputAdded` events\n/// on every successful call to `addInput`. This ensures that inputs can be\n/// retrieved by anyone at any time, without having to rely on centralized data\n/// providers.\n///\n/// From the perspective of this contract, inputs are encoding-agnostic byte\n/// arrays. It is up to the DApp to interpret, validate and act upon inputs.\ncontract InputBox is IInputBox {\n /// @notice Mapping from DApp address to list of input hashes.\n /// @dev See the `getNumberOfInputs`, `getInputHash` and `addInput` functions.\n mapping(address => bytes32[]) internal inputBoxes;\n\n function addInput(\n address _dapp,\n bytes calldata _input\n ) external override returns (bytes32) {\n bytes32[] storage inputBox = inputBoxes[_dapp];\n uint256 inboxInputIndex = inputBox.length;\n\n bytes32 inputHash = LibInput.computeInputHash(\n msg.sender,\n block.number,\n block.timestamp,\n _input,\n inboxInputIndex\n );\n\n // add input to correct inbox\n inputBox.push(inputHash);\n\n // block.number and timestamp can be retrieved by the event metadata itself\n emit InputAdded(_dapp, inboxInputIndex, msg.sender, _input);\n\n return inputHash;\n }\n\n function getNumberOfInputs(\n address _dapp\n ) external view override returns (uint256) {\n return inputBoxes[_dapp].length;\n }\n\n function getInputHash(\n address _dapp,\n uint256 _index\n ) external view override returns (bytes32) {\n return inputBoxes[_dapp][_index];\n }\n}\n" + }, + "contracts/library/LibInput.sol": { + "content": "// Copyright 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.8;\n\nimport {CanonicalMachine} from \"../common/CanonicalMachine.sol\";\n\n/// @title Input Library\nlibrary LibInput {\n using CanonicalMachine for CanonicalMachine.Log2Size;\n\n /// @notice Summarize input data in a single hash.\n /// @param sender `msg.sender`\n /// @param blockNumber `block.number`\n /// @param blockTimestamp `block.timestamp`\n /// @param input The input blob\n /// @param inboxInputIndex The index of the input in the input box\n /// @return The input hash\n function computeInputHash(\n address sender,\n uint256 blockNumber,\n uint256 blockTimestamp,\n bytes calldata input,\n uint256 inboxInputIndex\n ) internal pure returns (bytes32) {\n // Currently sending an input larger than driveSize surpasses the block gas limit\n // But we keep the following check in case this changes in the future\n require(\n input.length <=\n (1 << CanonicalMachine.INPUT_MAX_LOG2_SIZE.uint64OfSize()),\n \"input len: [0,driveSize]\"\n );\n\n bytes32 keccakMetadata = keccak256(\n abi.encode(\n sender,\n blockNumber,\n blockTimestamp,\n 0, //TODO decide how to deal with epoch index\n inboxInputIndex // input index in the input box\n )\n );\n\n bytes32 keccakInput = keccak256(input);\n\n return keccak256(abi.encode(keccakMetadata, keccakInput));\n }\n}\n" + }, + "contracts/library/LibOutputValidation.sol": { + "content": "// Copyright 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.8;\n\nimport {CanonicalMachine} from \"../common/CanonicalMachine.sol\";\nimport {MerkleV2} from \"@cartesi/util/contracts/MerkleV2.sol\";\nimport {OutputEncoding} from \"../common/OutputEncoding.sol\";\n\n/// @param inputIndex Which input, inside the epoch, the output belongs to\n/// @param outputIndex Index of output emitted by the input\n/// @param outputHashesRootHash Merkle root of hashes of outputs emitted by the input\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 uint64 inputIndex;\n uint64 outputIndex;\n bytes32 outputHashesRootHash;\n bytes32 vouchersEpochRootHash;\n bytes32 noticesEpochRootHash;\n bytes32 machineStateHash;\n bytes32[] keccakInHashesSiblings;\n bytes32[] outputHashesInEpochSiblings;\n}\n\n/// @title Output Validation Library\nlibrary LibOutputValidation {\n using CanonicalMachine for CanonicalMachine.Log2Size;\n\n /// @notice Make sure the output proof is valid, otherwise revert.\n /// @param v The output validity proof\n /// @param encodedOutput The encoded output\n /// @param epochHash The hash of the epoch in which the output was generated\n /// @param outputsEpochRootHash Either `v.vouchersEpochRootHash` (for vouchers)\n /// or `v.noticesEpochRootHash` (for notices)\n /// @param outputEpochLog2Size Either `EPOCH_VOUCHER_LOG2_SIZE` (for vouchers)\n /// or `EPOCH_NOTICE_LOG2_SIZE` (for notices)\n /// @param outputHashesLog2Size Either `VOUCHER_METADATA_LOG2_SIZE` (for vouchers)\n /// or `NOTICE_METADATA_LOG2_SIZE` (for notices)\n function validateEncodedOutput(\n OutputValidityProof calldata v,\n bytes memory encodedOutput,\n bytes32 epochHash,\n bytes32 outputsEpochRootHash,\n uint256 outputEpochLog2Size,\n uint256 outputHashesLog2Size\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 \"incorrect epochHash\"\n );\n\n // prove that output metadata memory range is contained in epoch's output memory range\n require(\n MerkleV2.getRootAfterReplacementInDrive(\n CanonicalMachine.getIntraMemoryRangePosition(\n v.inputIndex,\n CanonicalMachine.KECCAK_LOG2_SIZE\n ),\n CanonicalMachine.KECCAK_LOG2_SIZE.uint64OfSize(),\n outputEpochLog2Size,\n v.outputHashesRootHash,\n v.outputHashesInEpochSiblings\n ) == outputsEpochRootHash,\n \"incorrect outputsEpochRootHash\"\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 = MerkleV2.getMerkleRootFromBytes(\n abi.encodePacked(keccak256(encodedOutput)),\n CanonicalMachine.KECCAK_LOG2_SIZE.uint64OfSize()\n );\n\n // prove that Merkle root hash of bytes(hashOfOutput) is contained\n // in the output metadata array memory range\n require(\n MerkleV2.getRootAfterReplacementInDrive(\n CanonicalMachine.getIntraMemoryRangePosition(\n v.outputIndex,\n CanonicalMachine.KECCAK_LOG2_SIZE\n ),\n CanonicalMachine.KECCAK_LOG2_SIZE.uint64OfSize(),\n outputHashesLog2Size,\n merkleRootOfHashOfOutput,\n v.keccakInHashesSiblings\n ) == v.outputHashesRootHash,\n \"incorrect outputHashesRootHash\"\n );\n }\n\n /// @notice Make sure the output proof is valid, otherwise revert.\n /// @param v The output validity proof\n /// @param destination The address that will receive the payload through a message call\n /// @param payload The payload, which—in the case of Solidity contracts—encodes a function call\n /// @param epochHash The hash of the epoch in which the output was generated\n function validateVoucher(\n OutputValidityProof calldata v,\n address destination,\n bytes calldata payload,\n bytes32 epochHash\n ) internal pure {\n bytes memory encodedVoucher = OutputEncoding.encodeVoucher(\n destination,\n payload\n );\n validateEncodedOutput(\n v,\n encodedVoucher,\n epochHash,\n v.vouchersEpochRootHash,\n CanonicalMachine.EPOCH_VOUCHER_LOG2_SIZE.uint64OfSize(),\n CanonicalMachine.VOUCHER_METADATA_LOG2_SIZE.uint64OfSize()\n );\n }\n\n /// @notice Make sure the output proof is valid, otherwise revert.\n /// @param v The output validity proof\n /// @param notice The notice\n /// @param epochHash The hash of the epoch in which the output was generated\n function validateNotice(\n OutputValidityProof calldata v,\n bytes calldata notice,\n bytes32 epochHash\n ) internal pure {\n bytes memory encodedNotice = OutputEncoding.encodeNotice(notice);\n validateEncodedOutput(\n v,\n encodedNotice,\n epochHash,\n v.noticesEpochRootHash,\n CanonicalMachine.EPOCH_NOTICE_LOG2_SIZE.uint64OfSize(),\n CanonicalMachine.NOTICE_METADATA_LOG2_SIZE.uint64OfSize()\n );\n }\n\n /// @notice Get the position of a voucher on the bit mask.\n /// @param voucher The index of voucher from those generated by such input\n /// @param input The index of the input in the DApp's input box\n /// @return Position of the voucher on the bit mask\n function getBitMaskPosition(\n uint256 voucher,\n uint256 input\n ) internal pure returns (uint256) {\n // voucher * 2 ** 128 + input\n // this shouldn't overflow because it is impossible to have > 2**128 vouchers\n // and because we are assuming there will be < 2 ** 128 inputs on the input box\n return (((voucher << 128) | input));\n }\n\n /// @notice Validate input index range and get the inbox input index.\n /// @param v The output validity proof\n /// @param firstInputIndex The index of the first input of the epoch in the input box\n /// @param lastInputIndex The index of the last input of the epoch in the input box\n /// @return The index of the input in the DApp's input box\n /// @dev Reverts if epoch input index is not compatible with the provided input index range.\n function validateInputIndexRange(\n OutputValidityProof calldata v,\n uint256 firstInputIndex,\n uint256 lastInputIndex\n ) internal pure returns (uint256) {\n uint256 inboxInputIndex = firstInputIndex + v.inputIndex;\n\n require(\n inboxInputIndex <= lastInputIndex,\n \"inbox input index out of bounds\"\n );\n\n return inboxInputIndex;\n }\n}\n" + }, + "contracts/portals/ERC1155BatchPortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\nimport {IERC1155BatchPortal} from \"./IERC1155BatchPortal.sol\";\nimport {Portal} from \"./Portal.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\nimport {InputEncoding} from \"../common/InputEncoding.sol\";\n\n/// @title ERC-1155 Batch Transfer Portal\n///\n/// @notice This contract allows anyone to perform batch transfers of\n/// ERC-1155 tokens to a DApp while informing the off-chain machine.\ncontract ERC1155BatchPortal is Portal, IERC1155BatchPortal {\n /// @notice Constructs the portal.\n /// @param _inputBox The input box used by the portal\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\n\n function depositBatchERC1155Token(\n IERC1155 _token,\n address _dapp,\n uint256[] calldata _tokenIds,\n uint256[] calldata _values,\n bytes calldata _baseLayerData,\n bytes calldata _execLayerData\n ) external override {\n _token.safeBatchTransferFrom(\n msg.sender,\n _dapp,\n _tokenIds,\n _values,\n _baseLayerData\n );\n\n bytes memory input = InputEncoding.encodeBatchERC1155Deposit(\n _token,\n msg.sender,\n _tokenIds,\n _values,\n _baseLayerData,\n _execLayerData\n );\n\n inputBox.addInput(_dapp, input);\n }\n}\n" + }, + "contracts/portals/ERC1155SinglePortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\nimport {IERC1155SinglePortal} from \"./IERC1155SinglePortal.sol\";\nimport {Portal} from \"./Portal.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\nimport {InputEncoding} from \"../common/InputEncoding.sol\";\n\n/// @title ERC-1155 Single Transfer Portal\n///\n/// @notice This contract allows anyone to perform single transfers of\n/// ERC-1155 tokens to a DApp while informing the off-chain machine.\ncontract ERC1155SinglePortal is Portal, IERC1155SinglePortal {\n /// @notice Constructs the portal.\n /// @param _inputBox The input box used by the portal\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\n\n function depositSingleERC1155Token(\n IERC1155 _token,\n address _dapp,\n uint256 _tokenId,\n uint256 _value,\n bytes calldata _baseLayerData,\n bytes calldata _execLayerData\n ) external override {\n _token.safeTransferFrom(\n msg.sender,\n _dapp,\n _tokenId,\n _value,\n _baseLayerData\n );\n\n bytes memory input = InputEncoding.encodeSingleERC1155Deposit(\n _token,\n msg.sender,\n _tokenId,\n _value,\n _baseLayerData,\n _execLayerData\n );\n\n inputBox.addInput(_dapp, input);\n }\n}\n" + }, + "contracts/portals/ERC20Portal.sol": { + "content": "// Copyright 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.8;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {IERC20Portal} from \"./IERC20Portal.sol\";\nimport {Portal} from \"./Portal.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\nimport {InputEncoding} from \"../common/InputEncoding.sol\";\n\n/// @title ERC-20 Portal\n///\n/// @notice This contract allows anyone to perform transfers of\n/// ERC-20 tokens to a DApp while informing the off-chain machine.\ncontract ERC20Portal is Portal, IERC20Portal {\n /// @notice Constructs the portal.\n /// @param _inputBox The input box used by the portal\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\n\n function depositERC20Tokens(\n IERC20 _token,\n address _dapp,\n uint256 _amount,\n bytes calldata _execLayerData\n ) external override {\n bool success = _token.transferFrom(msg.sender, _dapp, _amount);\n\n bytes memory input = InputEncoding.encodeERC20Deposit(\n success,\n _token,\n msg.sender,\n _amount,\n _execLayerData\n );\n\n inputBox.addInput(_dapp, input);\n }\n}\n" + }, + "contracts/portals/ERC721Portal.sol": { + "content": "// Copyright 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.8;\n\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\nimport {IERC721Portal} from \"./IERC721Portal.sol\";\nimport {Portal} from \"./Portal.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\nimport {InputEncoding} from \"../common/InputEncoding.sol\";\n\n/// @title ERC-721 Portal\n///\n/// @notice This contract allows anyone to perform transfers of\n/// ERC-721 tokens to a DApp while informing the off-chain machine.\ncontract ERC721Portal is Portal, IERC721Portal {\n /// @notice Constructs the portal.\n /// @param _inputBox The input box used by the portal\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\n\n function depositERC721Token(\n IERC721 _token,\n address _dapp,\n uint256 _tokenId,\n bytes calldata _baseLayerData,\n bytes calldata _execLayerData\n ) external override {\n _token.safeTransferFrom(msg.sender, _dapp, _tokenId, _baseLayerData);\n\n bytes memory input = InputEncoding.encodeERC721Deposit(\n _token,\n msg.sender,\n _tokenId,\n _baseLayerData,\n _execLayerData\n );\n\n inputBox.addInput(_dapp, input);\n }\n}\n" + }, + "contracts/portals/EtherPortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IEtherPortal} from \"./IEtherPortal.sol\";\nimport {Portal} from \"./Portal.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\nimport {InputEncoding} from \"../common/InputEncoding.sol\";\n\n/// @title Ether Portal\n///\n/// @notice This contract allows anyone to perform transfers of\n/// Ether to a DApp while informing the off-chain machine.\ncontract EtherPortal is Portal, IEtherPortal {\n /// @notice Constructs the portal.\n /// @param _inputBox The input box used by the portal\n constructor(IInputBox _inputBox) Portal(_inputBox) {}\n\n function depositEther(\n address _dapp,\n bytes calldata _execLayerData\n ) external payable override {\n // We used to call `transfer()` but it's not considered safe,\n // as it assumes gas costs are immutable (they are not).\n (bool success, ) = _dapp.call{value: msg.value}(\"\");\n require(success, \"EtherPortal: transfer failed\");\n\n bytes memory input = InputEncoding.encodeEtherDeposit(\n msg.sender,\n msg.value,\n _execLayerData\n );\n\n inputBox.addInput(_dapp, input);\n }\n}\n" + }, + "contracts/portals/IERC1155BatchPortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IPortal} from \"./IPortal.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/// @title ERC-1155 Batch Transfer Portal interface\ninterface IERC1155BatchPortal is IPortal {\n // Permissionless functions\n\n /// @notice Transfer a batch of ERC-1155 tokens to a DApp and add an input to\n /// the DApp's input box to signal such operation.\n ///\n /// The caller must enable approval for the portal to manage all of their tokens\n /// beforehand, by calling the `setApprovalForAll` function in the token contract.\n ///\n /// @param _token The ERC-1155 token contract\n /// @param _dapp The address of the DApp\n /// @param _tokenIds The identifiers of the tokens being transferred\n /// @param _values Transfer amounts per token type\n /// @param _baseLayerData Additional data to be interpreted by the base layer\n /// @param _execLayerData Additional data to be interpreted by the execution layer\n ///\n /// @dev Please make sure `_tokenIds` and `_values` have the same length.\n function depositBatchERC1155Token(\n IERC1155 _token,\n address _dapp,\n uint256[] calldata _tokenIds,\n uint256[] calldata _values,\n bytes calldata _baseLayerData,\n bytes calldata _execLayerData\n ) external;\n}\n" + }, + "contracts/portals/IERC1155SinglePortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IPortal} from \"./IPortal.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/// @title ERC-1155 Single Transfer Portal interface\ninterface IERC1155SinglePortal is IPortal {\n // Permissionless functions\n\n /// @notice Transfer an ERC-1155 token to a DApp and add an input to\n /// the DApp's input box to signal such operation.\n ///\n /// The caller must enable approval for the portal to manage all of their tokens\n /// beforehand, by calling the `setApprovalForAll` function in the token contract.\n ///\n /// @param _token The ERC-1155 token contract\n /// @param _dapp The address of the DApp\n /// @param _tokenId The identifier of the token being transferred\n /// @param _value Transfer amount\n /// @param _baseLayerData Additional data to be interpreted by the base layer\n /// @param _execLayerData Additional data to be interpreted by the execution layer\n function depositSingleERC1155Token(\n IERC1155 _token,\n address _dapp,\n uint256 _tokenId,\n uint256 _value,\n bytes calldata _baseLayerData,\n bytes calldata _execLayerData\n ) external;\n}\n" + }, + "contracts/portals/IERC20Portal.sol": { + "content": "// Copyright 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.8;\n\nimport {IPortal} from \"./IPortal.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ERC-20 Portal interface\ninterface IERC20Portal is IPortal {\n // Permissionless functions\n\n /// @notice Transfer ERC-20 tokens to a DApp and add an input to\n /// the DApp's input box to signal such operation.\n ///\n /// The caller must allow the portal to withdraw at least `_amount` tokens\n /// from their account beforehand, by calling the `approve` function in the\n /// token contract.\n ///\n /// @param _token The ERC-20 token contract\n /// @param _dapp The address of the DApp\n /// @param _amount The amount of tokens to be transferred\n /// @param _execLayerData Additional data to be interpreted by the execution layer\n function depositERC20Tokens(\n IERC20 _token,\n address _dapp,\n uint256 _amount,\n bytes calldata _execLayerData\n ) external;\n}\n" + }, + "contracts/portals/IERC721Portal.sol": { + "content": "// Copyright 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.8;\n\nimport {IPortal} from \"./IPortal.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Portal interface\ninterface IERC721Portal is IPortal {\n // Permissionless functions\n\n /// @notice Transfer an ERC-721 token to a DApp and add an input to\n /// the DApp's input box to signal such operation.\n ///\n /// The caller must change the approved address for the ERC-721 token\n /// to the portal address beforehand, by calling the `approve` function in the\n /// token contract.\n ///\n /// @param _token The ERC-721 token contract\n /// @param _dapp The address of the DApp\n /// @param _tokenId The identifier of the token being transferred\n /// @param _baseLayerData Additional data to be interpreted by the base layer\n /// @param _execLayerData Additional data to be interpreted by the execution layer\n function depositERC721Token(\n IERC721 _token,\n address _dapp,\n uint256 _tokenId,\n bytes calldata _baseLayerData,\n bytes calldata _execLayerData\n ) external;\n}\n" + }, + "contracts/portals/IEtherPortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IPortal} from \"./IPortal.sol\";\n\n/// @title Ether Portal interface\ninterface IEtherPortal is IPortal {\n // Permissionless functions\n\n /// @notice Transfer Ether to a DApp and add an input to\n /// the DApp's input box to signal such operation.\n ///\n /// All the value sent through this function is forwarded to the DApp.\n ///\n /// @param _dapp The address of the DApp\n /// @param _execLayerData Additional data to be interpreted by the execution layer\n function depositEther(\n address _dapp,\n bytes calldata _execLayerData\n ) external payable;\n}\n" + }, + "contracts/portals/IPortal.sol": { + "content": "// Copyright 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.8;\n\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\n\n/// @title Portal interface\ninterface IPortal {\n // Permissionless functions\n\n /// @notice Get the input box used by this portal.\n /// @return The input box\n function getInputBox() external view returns (IInputBox);\n}\n" + }, + "contracts/portals/Portal.sol": { + "content": "// Copyright 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.8;\n\nimport {IPortal} from \"./IPortal.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\n\n/// @title Portal\n/// @notice This contract serves as a base for all the other portals.\ncontract Portal is IPortal {\n /// @notice The input box used by the portal.\n IInputBox internal immutable inputBox;\n\n /// @notice Constructs the portal.\n /// @param _inputBox The input box used by the portal\n constructor(IInputBox _inputBox) {\n inputBox = _inputBox;\n }\n\n function getInputBox() external view override returns (IInputBox) {\n return inputBox;\n }\n}\n" + }, + "contracts/relays/DAppAddressRelay.sol": { + "content": "// Copyright 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.8;\n\nimport {IDAppAddressRelay} from \"./IDAppAddressRelay.sol\";\nimport {Relay} from \"./Relay.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\nimport {InputEncoding} from \"../common/InputEncoding.sol\";\n\n/// @title DApp Address Relay\n///\n/// @notice This contract allows anyone to inform the off-chain machine\n/// of the address of the DApp contract in a trustless and permissionless way.\ncontract DAppAddressRelay is Relay, IDAppAddressRelay {\n /// @notice Constructs the relay.\n /// @param _inputBox The input box used by the relay\n constructor(IInputBox _inputBox) Relay(_inputBox) {}\n\n function relayDAppAddress(address _dapp) external override {\n bytes memory input = InputEncoding.encodeDAppAddressRelay(_dapp);\n inputBox.addInput(_dapp, input);\n }\n}\n" + }, + "contracts/relays/IDAppAddressRelay.sol": { + "content": "// Copyright 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.8;\n\nimport {IRelay} from \"./IRelay.sol\";\n\n/// @title DApp Address Relay interface\ninterface IDAppAddressRelay is IRelay {\n // Permissionless functions\n\n /// @notice Add an input to a DApp's input box with its address.\n /// @param _dapp The address of the DApp\n function relayDAppAddress(address _dapp) external;\n}\n" + }, + "contracts/relays/IRelay.sol": { + "content": "// Copyright 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.8;\n\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\n\n/// @title Relay interface\ninterface IRelay {\n // Permissionless functions\n\n /// @notice Get the input box used by this relay.\n /// @return The input box\n function getInputBox() external view returns (IInputBox);\n}\n" + }, + "contracts/relays/Relay.sol": { + "content": "// Copyright 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.8;\n\nimport {IRelay} from \"./IRelay.sol\";\nimport {IInputBox} from \"../inputs/IInputBox.sol\";\n\n/// @title Relay\n/// @notice This contract serves as a base for all the other relays.\ncontract Relay is IRelay {\n /// @notice The input box used by the relay.\n IInputBox internal immutable inputBox;\n\n /// @notice Constructs the relay.\n /// @param _inputBox The input box used by the relay\n constructor(IInputBox _inputBox) {\n inputBox = _inputBox;\n }\n\n function getInputBox() external view override returns (IInputBox) {\n return inputBox;\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/docker-bake.hcl b/docker-bake.hcl index 0cf0fbd..a0cd8e6 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -22,7 +22,7 @@ target "server" { context = "./std-rootfs" target = "server-stage" contexts = { - dapp = "target:dapp" + fs = "target:fs" } } @@ -30,7 +30,7 @@ target "console" { context = "./std-rootfs" target = "console-stage" contexts = { - dapp = "target:dapp" + fs = "target:fs" } } @@ -38,8 +38,12 @@ target "machine" { context = "./std-rootfs" target = "machine-stage" contexts = { - dapp = "target:dapp" + server = "target:server" } } - +target "dapp" { + contexts = { + toolchain-python = "target:toolchain-python" + } +} diff --git a/docker-bake.override.hcl b/docker-bake.override.hcl index 44a5cbc..076c5c1 100644 --- a/docker-bake.override.hcl +++ b/docker-bake.override.hcl @@ -1,10 +1,4 @@ -target "dapp" { - contexts = { - toolchain-python = "target:toolchain-python" - } -} - variable "TAG" { default = "devel" } diff --git a/docker-compose-deploy.yml b/docker-compose-deploy.yml deleted file mode 100644 index 97ebd92..0000000 --- a/docker-compose-deploy.yml +++ /dev/null @@ -1,96 +0,0 @@ -version: "3.9" - -services: - hardhat: - image: juztamau5/rollups-hardhat:0.8.2 - command: - [ - "node", - "--network", - "hardhat", - "--export", - "/opt/cartesi/share/blockchain/localhost.json", - ] - init: true - ports: - - "8545:8545" - healthcheck: - test: - ["CMD", "test", "-f", "/opt/cartesi/share/blockchain/localhost.json"] - interval: 10s - timeout: 30s - retries: 15 - volumes: - - ./deployments:/app/rollups/deployments - - ./export:/opt/cartesi/share/blockchain - - server_manager: - restart: always - ports: - - "5001:5001" - healthcheck: - test: ["CMD", "grpc-health-probe", "-addr=:5001"] - interval: 10s - timeout: 5s - retries: 5 - volumes: - - machine:/opt/cartesi/share/dapp-bin - environment: - - SERVER_MANAGER_LOG_LEVEL=warning - - REMOTE_CARTESI_MACHINE_LOG_LEVEL=info - - deployer: - image: juztamau5/rollups-cli:0.8.2 - restart: on-failure - depends_on: - hardhat: - condition: service_healthy - server_manager: - condition: service_healthy - command: - [ - "create", - "--rpc", - "http://hardhat:8545", - "--deploymentFile", - "/opt/cartesi/share/blockchain/localhost.json", - "--mnemonic", - "test test test test test test test test test test test junk", - "--templateHashFile", - "/opt/cartesi/share/dapp-bin/hash", - "--outputFile", - "/deployments/localhost/dapp.json", - ] - volumes: - - machine:/opt/cartesi/share/dapp-bin:ro - - ./deployments:/deployments - - ./export:/opt/cartesi/share/blockchain - - ultrachess_deployer: - image: juztamau5/ultrachess-deployer:1.0.0 - restart: on-failure - depends_on: - hardhat: - condition: service_healthy - command: - [ - "deploy", - "--network", - "docker", - "--export", - "/opt/cartesi/share/blockchain/localhost-ultrachess.json", - ] - volumes: - - ./deployments:/app/rollups/deployments - - ./export:/opt/cartesi/share/blockchain - - finished: - image: hello-world:latest # Close to scratch image - depends_on: - deployer: - condition: service_completed_successfully - ultrachess_deployer: - condition: service_completed_successfully - -volumes: - machine: {} diff --git a/docker-compose-host-testnet.yml b/docker-compose-host-testnet.yml index 9b0c05e..555ca24 100644 --- a/docker-compose-host-testnet.yml +++ b/docker-compose-host-testnet.yml @@ -2,7 +2,6 @@ version: "3" services: server_manager: - image: cartesi/host-server-manager:0.6.1 ports: - "5004:5004" - - "5002:5002" \ No newline at end of file + - "5002:5002" diff --git a/docker-compose-host.yml b/docker-compose-host.yml index 8950900..9000034 100644 --- a/docker-compose-host.yml +++ b/docker-compose-host.yml @@ -2,25 +2,24 @@ version: "3" services: server_manager: - image: cartesi/host-server-manager:0.7.0 ports: - "5004:5004" environment: - RUST_LOG=warn deployer: - command: [ + command: + [ "create", "--rpc", "http://hardhat:8545", "--deploymentFile", - "/opt/cartesi/share/blockchain/localhost.json", + "/opt/cartesi/share/deployments/localhost.json", "--mnemonic", "test test test test test test test test test test test junk", # template hash is not relevant in host mode, so we can specify hash zero "--templateHash", "0x0000000000000000000000000000000000000000000000000000000000000000", "--outputFile", - "/deployments/localhost/dapp.json", - + "/deployments/localhost/dapp.json" ] diff --git a/docker-compose-testnet.yml b/docker-compose-testnet.yml index d1c146c..feaeb64 100644 --- a/docker-compose-testnet.yml +++ b/docker-compose-testnet.yml @@ -1,39 +1,16 @@ version: "3.9" -x-credentials: &postgres-config +x-credentials: + &postgres-config POSTGRES_HOSTNAME: database POSTGRES_PORT: "5432" POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: postgres - POSTGRES_MIGRATION_FOLDER: /usr/local/bin/migrations/ services: - rollups_dispatcher: - image: cartesi/rollups-dispatcher:0.8.2 - command: - [ - "--rd-dapp-contract-address-file", - "/deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.json", - "--rd-initial-epoch", - "0", - "--sc-grpc-endpoint", - "http://state_server:50051", - "--sc-default-confirmations", - "${BLOCK_CONFIRMATIONS:?undefined BLOCK_CONFIRMATIONS}", - "--tx-provider-http-endpoint", - "${RPC_URL:?undefined RPC_URL}", - "--tx-mnemonic", - "${MNEMONIC:?undefined MNEMONIC}", - "--tx-chain-id", - "${CHAIN_ID:?undefined CHAIN_ID}", - "--tx-chain-is-legacy", - "${TX_LEGACY:-false}", - "--tx-default-confirmations", - "${BLOCK_CONFIRMATIONS_TX:?undefined BLOCK_CONFIRMATIONS_TX}", - "--redis-endpoint", - "redis://redis:6379", - ] + dispatcher: + image: juztamau5/rollups-dispatcher:0.9.1 restart: always depends_on: state_server: @@ -42,54 +19,41 @@ services: condition: service_healthy environment: RUST_LOG: info + RD_DAPP_DEPLOYMENT_FILE: /deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.json + RD_ROLLUPS_DEPLOYMENT_FILE: /opt/cartesi/share/deployments/${NETWORK:?undefined NETWORK}.json + RD_EPOCH_DURATION: 86400 + SC_GRPC_ENDPOINT: http://state_server:50051 + SC_DEFAULT_CONFIRMATIONS: ${BLOCK_CONFIRMATIONS:?undefined BLOCK_CONFIRMATIONS} + TX_PROVIDER_HTTP_ENDPOINT: ${RPC_URL:?undefined RPC_URL} + TX_MNEMONIC: ${MNEMONIC:?undefined MNEMONIC} + TX_CHAIN_ID: ${CHAIN_ID:?undefined CHAIN_ID} + TX_CHAIN_IS_LEGACY: ${TX_LEGACY:-false} + TX_DEFAULT_CONFIRMATIONS: ${BLOCK_CONFIRMATIONS_TX:?undefined BLOCK_CONFIRMATIONS_TX} + REDIS_ENDPOINT: redis://redis:6379 volumes: - - blockchain-data:/opt/cartesi/share/blockchain:ro - - ./deployments:/deployments + - ./deployments:/deployments:ro state_server: - image: cartesi/rollups-state-server:0.8.2 - command: - [ - "--sf-genesis-block", - "0x1", - "--sf-safety-margin", - "20", - "--bh-http-endpoint", - "${RPC_URL:?undefined RPC_URL}", - "--bh-ws-endpoint", - "${WSS_URL:?undefined WSS_URL}", - "--bh-block-timeout", - "120", - ] + image: cartesi/rollups-state-server:0.9.1 restart: always healthcheck: - test: ["CMD", "grpc-health-probe", "-addr=:50051"] + test: [ "CMD-SHELL", "bash -c 'echo \"\" > /dev/tcp/127.0.0.1/50051;'" ] interval: 10s timeout: 5s retries: 5 - volumes: - - blockchain-data:/opt/cartesi/share/blockchain:ro environment: RUST_LOG: info + SF_GENESIS_BLOCK: 0x1 + SF_SAFETY_MARGIN: 20 + BH_HTTP_ENDPOINT: ${RPC_URL:?undefined RPC_URL} + BH_WS_ENDPOINT: ${WSS_URL:?undefined WSS_URL} + BH_BLOCK_TIMEOUT: 120 - server_manager_broker_proxy: - image: cartesi/rollups-server-manager-broker-proxy:0.8.2 - command: - [ - "--chain-id", - "${CHAIN_ID:?undefined CHAIN_ID}", - "--dapp-contract-address-file", - "/deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.json", - "--redis-endpoint", - "redis://redis:6379", - "--server-manager-endpoint", - "http://server_manager:5001", - "--session-id", - "default_rollups_id", - ] + advance_runner: + image: cartesi/rollups-advance-runner:0.9.1 restart: always healthcheck: - test: ["CMD", "curl", "--fail", "localhost:8080/healthz"] + test: [ "CMD", "curl", "--fail", "localhost:8080/healthz" ] interval: 10s timeout: 5s retries: 5 @@ -99,34 +63,33 @@ services: server_manager: condition: service_healthy volumes: - - ./deployments:/deployments + - ./deployments:/deployments:ro + - machine:/var/opt/cartesi/machine-snapshots environment: RUST_LOG: info + SERVER_MANAGER_ENDPOINT: http://server_manager:5001 + SESSION_ID: default_rollups_id + REDIS_ENDPOINT: redis://redis:6379 + CHAIN_ID: ${CHAIN_ID:?undefined CHAIN_ID} + DAPP_CONTRACT_ADDRESS_FILE: /deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.json + SNAPSHOT_DIR: /var/opt/cartesi/machine-snapshots + SNAPSHOT_LATEST: /var/opt/cartesi/machine-snapshots/latest server_manager: restart: always healthcheck: - test: ["CMD", "grpc-health-probe", "-addr=:5001"] + test: [ "CMD-SHELL", "bash -c 'echo \"\" > /dev/tcp/127.0.0.1/5001;'" ] interval: 10s timeout: 5s retries: 5 volumes: - - machine:/opt/cartesi/share/dapp-bin + - machine:/var/opt/cartesi/machine-snapshots environment: - SERVER_MANAGER_LOG_LEVEL=warning - REMOTE_CARTESI_MACHINE_LOG_LEVEL=info - rollups_inspect_server: - image: cartesi/rollups-inspect-server:0.8.2 - command: - [ - "--inspect-server-address", - "0.0.0.0:5005", - "--server-manager-address", - "server_manager:5001", - "--session-id", - "default_rollups_id", - ] + inspect_server: + image: cartesi/rollups-inspect-server:0.9.1 restart: always ports: - "5005:5005" @@ -135,43 +98,29 @@ services: condition: service_healthy environment: RUST_LOG: info + INSPECT_SERVER_ADDRESS: 0.0.0.0:5005 + SERVER_MANAGER_ADDRESS: server_manager:5001 + SESSION_ID: default_rollups_id - rollups_indexer: - image: cartesi/rollups-indexer:0.8.2 - command: - [ - "--dapp-contract-address-file", - "/deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.json", - "--session-id", - "default_rollups_id", - "--initial-epoch", - "0", - "--interval", - "10", - "--confirmations", - "${BLOCK_CONFIRMATIONS:?undefined BLOCK_CONFIRMATIONS}", - "--state-server-endpoint", - "http://state_server:50051", - "--mm-endpoint", - "http://server_manager:5001", - ] + indexer: + image: cartesi/rollups-indexer:0.9.1 restart: always depends_on: - state_server: - condition: service_healthy - server_manager: - condition: service_healthy database: condition: service_healthy + redis: + condition: service_healthy environment: <<: *postgres-config RUST_LOG: info + REDIS_ENDPOINT: redis://redis:6379 + CHAIN_ID: ${CHAIN_ID:?undefined CHAIN_ID} + DAPP_CONTRACT_ADDRESS_FILE: /deployments/${NETWORK:?undefined NETWORK}/${DAPP_NAME:?undefined DAPP_NAME}.json volumes: - - blockchain-data:/opt/cartesi/share/blockchain - - ./deployments:/deployments + - ./deployments:/deployments:ro - query_server: - image: cartesi/query-server:0.8.2 + graphql_server: + image: cartesi/rollups-graphql-server:0.9.1 ports: - "4000:4000" depends_on: @@ -188,7 +137,7 @@ services: ports: - 5432:5432 healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres || exit 1"] + test: [ "CMD-SHELL", "pg_isready -U postgres || exit 1" ] interval: 10s timeout: 5s retries: 5 @@ -203,7 +152,7 @@ services: - 6379:6379 restart: always healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 5 @@ -211,7 +160,6 @@ services: - redis-data:/data volumes: - blockchain-data: {} machine: {} database-data: {} redis-data: {} diff --git a/docker-compose.yml b/docker-compose.yml index e82be87..5c9d924 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,124 +1,97 @@ version: "3.9" -x-credentials: &postgres-config +x-credentials: + &postgres-config POSTGRES_HOSTNAME: database POSTGRES_PORT: "5432" POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: postgres - POSTGRES_MIGRATION_FOLDER: /usr/local/bin/migrations/ services: hardhat: - image: cartesi/rollups-hardhat:0.8.2 + image: juztamau5/rollups-hardhat:0.9.1 command: [ "node", "--network", "hardhat", "--export", - "/opt/cartesi/share/blockchain/localhost.json", + "/opt/cartesi/share/deployments/localhost.json" ] init: true ports: - "8545:8545" healthcheck: test: - ["CMD", "test", "-f", "/opt/cartesi/share/blockchain/localhost.json"] + [ + "CMD", + "test", + "-f", + "/opt/cartesi/share/deployments/localhost.json" + ] interval: 30s timeout: 30s retries: 5 volumes: - - blockchain-data:/opt/cartesi/share/blockchain + - blockchain-data:/opt/cartesi/share/deployments - ./deployments:/app/rollups/deployments - rollups_dispatcher: - image: cartesi/rollups-dispatcher:0.8.2 - command: - [ - "--rd-dapp-contract-address-file", - "/deployments/localhost/dapp.json", - "--rd-initial-epoch", - "0", - "--sc-grpc-endpoint", - "http://state_server:50051", - "--sc-default-confirmations", - "1", - "--tx-provider-http-endpoint", - "http://hardhat:8545", - "--tx-mnemonic", - "test test test test test test test test test test test junk", - "--tx-chain-id", - "31337", - "--tx-chain-is-legacy", - "${TX_LEGACY:-false}", - "--tx-default-confirmations", - "2", - "--redis-endpoint", - "redis://redis:6379", - ] + dispatcher: + image: juztamau5/rollups-dispatcher:0.9.1 restart: always depends_on: hardhat: condition: service_healthy hardhat_set_interval: condition: service_completed_successfully + deployer: + condition: service_completed_successfully state_server: condition: service_healthy redis: condition: service_healthy environment: RUST_LOG: info + RD_DAPP_DEPLOYMENT_FILE: /deployments/localhost/dapp.json + RD_ROLLUPS_DEPLOYMENT_FILE: /opt/cartesi/share/deployments/localhost.json + RD_EPOCH_DURATION: 86400 + SC_GRPC_ENDPOINT: http://state_server:50051 + SC_DEFAULT_CONFIRMATIONS: 1 + TX_PROVIDER_HTTP_ENDPOINT: http://hardhat:8545 + TX_MNEMONIC: "test test test test test test test test test test test junk" + TX_CHAIN_ID: 31337 + TX_CHAIN_IS_LEGACY: ${TX_LEGACY:-false} + TX_DEFAULT_CONFIRMATIONS: 2 + REDIS_ENDPOINT: redis://redis:6379 volumes: - - blockchain-data:/opt/cartesi/share/blockchain:ro - - ./deployments:/deployments + - blockchain-data:/opt/cartesi/share/deployments:ro + - ./deployments:/deployments:ro state_server: - image: cartesi/rollups-state-server:0.8.2 - command: [ - "--sf-genesis-block", - "0x1", - "--sf-safety-margin", - "1", - "--bh-http-endpoint", - "http://hardhat:8545", - "--bh-ws-endpoint", - "ws://hardhat:8545", - "--bh-block-timeout", - "8", # just a few seconds more than the configured automatic interval mining - ] + image: cartesi/rollups-state-server:0.9.1 restart: always healthcheck: - test: ["CMD", "grpc-health-probe", "-addr=:50051"] + test: ["CMD-SHELL","bash -c 'echo \"\" > /dev/tcp/127.0.0.1/50051;'"] interval: 10s timeout: 5s retries: 5 depends_on: hardhat: condition: service_healthy - volumes: - - blockchain-data:/opt/cartesi/share/blockchain:ro environment: RUST_LOG: info + SF_GENESIS_BLOCK: 0x1 + SF_SAFETY_MARGIN: 1 + BH_HTTP_ENDPOINT: http://hardhat:8545 + BH_WS_ENDPOINT: ws://hardhat:8545 + BH_BLOCK_TIMEOUT: 8 - server_manager_broker_proxy: - image: cartesi/rollups-server-manager-broker-proxy:0.8.2 - command: - [ - "--chain-id", - "31337", - "--dapp-contract-address-file", - "/deployments/localhost/dapp.json", - "--redis-endpoint", - "redis://redis:6379", - "--server-manager-endpoint", - "http://server_manager:5001", - "--session-id", - "default_rollups_id", - ] + advance_runner: + image: cartesi/rollups-advance-runner:0.9.1 restart: always healthcheck: - test: ["CMD", "curl", "--fail", "localhost:8080/healthz"] + test: [ "CMD", "curl", "--fail", "localhost:8080/healthz" ] interval: 10s timeout: 5s retries: 5 @@ -130,27 +103,35 @@ services: deployer: condition: service_completed_successfully volumes: - - ./deployments:/deployments + - ./deployments:/deployments:ro + - machine:/var/opt/cartesi/machine-snapshots environment: RUST_LOG: info + SERVER_MANAGER_ENDPOINT: http://server_manager:5001 + SESSION_ID: default_rollups_id + REDIS_ENDPOINT: redis://redis:6379 + CHAIN_ID: 31337 + DAPP_CONTRACT_ADDRESS_FILE: /deployments/localhost/dapp.json + SNAPSHOT_DIR: /var/opt/cartesi/machine-snapshots + SNAPSHOT_LATEST: /var/opt/cartesi/machine-snapshots/latest server_manager: restart: always ports: - "5001:5001" healthcheck: - test: ["CMD", "grpc-health-probe", "-addr=:5001"] + test: ["CMD-SHELL","bash -c 'echo \"\" > /dev/tcp/127.0.0.1/5001;'"] interval: 10s timeout: 5s retries: 5 volumes: - - machine:/opt/cartesi/share/dapp-bin + - machine:/var/opt/cartesi/machine-snapshots environment: - SERVER_MANAGER_LOG_LEVEL=warning - REMOTE_CARTESI_MACHINE_LOG_LEVEL=info deployer: - image: cartesi/rollups-cli:0.8.2 + image: juztamau5/rollups-cli:0.9.1 restart: on-failure depends_on: hardhat: @@ -163,17 +144,17 @@ services: "--rpc", "http://hardhat:8545", "--deploymentFile", - "/opt/cartesi/share/blockchain/localhost.json", + "/opt/cartesi/share/deployments/localhost.json", "--mnemonic", "test test test test test test test test test test test junk", "--templateHashFile", - "/opt/cartesi/share/dapp-bin/hash", + "/var/opt/cartesi/machine-snapshots/0_0/hash", "--outputFile", - "/deployments/localhost/dapp.json", + "/deployments/localhost/dapp.json" ] volumes: - - blockchain-data:/opt/cartesi/share/blockchain - - machine:/opt/cartesi/share/dapp-bin:ro + - blockchain-data:/opt/cartesi/share/deployments:ro + - machine:/var/opt/cartesi/machine-snapshots:ro - ./deployments:/deployments hardhat_stop_automine: @@ -188,7 +169,7 @@ services: [ "--data", '{"id":1337,"jsonrpc":"2.0","method":"evm_setAutomine","params":[false]}', - "http://hardhat:8545", + "http://hardhat:8545" ] hardhat_set_interval: @@ -203,20 +184,11 @@ services: [ "--data", '{"id":1337,"jsonrpc":"2.0","method":"evm_setIntervalMining","params":[5000]}', - "http://hardhat:8545", + "http://hardhat:8545" ] - rollups_inspect_server: - image: cartesi/rollups-inspect-server:0.8.2 - command: - [ - "--inspect-server-address", - "0.0.0.0:5005", - "--server-manager-address", - "server_manager:5001", - "--session-id", - "default_rollups_id", - ] + inspect_server: + image: cartesi/rollups-inspect-server:0.9.1 restart: always ports: - "5005:5005" @@ -225,47 +197,31 @@ services: condition: service_healthy environment: RUST_LOG: info + INSPECT_SERVER_ADDRESS: 0.0.0.0:5005 + SERVER_MANAGER_ADDRESS: server_manager:5001 + SESSION_ID: default_rollups_id - rollups_indexer: - image: cartesi/rollups-indexer:0.8.2 - command: - [ - "--dapp-contract-address-file", - "/deployments/localhost/dapp.json", - "--session-id", - "default_rollups_id", - "--initial-epoch", - "0", - "--interval", - "10", - "--confirmations", - "1", - "--state-server-endpoint", - "http://state_server:50051", - "--mm-endpoint", - "http://server_manager:5001", - ] + indexer: + image: cartesi/rollups-indexer:0.9.1 restart: always depends_on: - hardhat: - condition: service_healthy - hardhat_set_interval: - condition: service_completed_successfully - state_server: - condition: service_healthy - server_manager: - condition: service_healthy database: condition: service_healthy + redis: + condition: service_healthy + deployer: + condition: service_completed_successfully environment: <<: *postgres-config RUST_LOG: info + REDIS_ENDPOINT: redis://redis:6379 + CHAIN_ID: 31337 + DAPP_CONTRACT_ADDRESS_FILE: /deployments/localhost/dapp.json volumes: - - blockchain-data:/opt/cartesi/share/blockchain - - ./deployments:/deployments + - ./deployments:/deployments:ro - query_server: - image: cartesi/query-server:0.8.2 + graphql_server: + image: cartesi/rollups-graphql-server:0.9.1 ports: - "4000:4000" depends_on: @@ -282,7 +238,7 @@ services: ports: - 5432:5432 healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres || exit 1"] + test: [ "CMD-SHELL", "pg_isready -U postgres || exit 1" ] interval: 10s timeout: 5s retries: 5 @@ -297,7 +253,7 @@ services: - 6379:6379 restart: always healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 5 diff --git a/front/package.json b/front/package.json index 6cef6c4..d7ff5aa 100644 --- a/front/package.json +++ b/front/package.json @@ -58,7 +58,7 @@ "urql": "^3.0.3" }, "devDependencies": { - "@cartesi/rollups": "^0.8.2", + "@cartesi/rollups": "^0.9.1", "@cartesi/token": "^1.8.0", "@graphql-codegen/cli": "^3.2.1", "@graphql-codegen/typed-document-node": "^3.0.1", diff --git a/front/src/ether/chains.js b/front/src/ether/chains.js index a32c3ac..a424ed8 100644 --- a/front/src/ether/chains.js +++ b/front/src/ether/chains.js @@ -6,7 +6,7 @@ * See the file LICENSE for more information. */ -import CartesiToken from "../../../deployments/localhost/CartesiToken.json"; +import CartesiToken from "../../../export/localhost.json"; const ETH = { name: "Ether", diff --git a/front/src/ether/contracts.js b/front/src/ether/contracts.js index 1c9ce3f..dbbd6d4 100644 --- a/front/src/ether/contracts.js +++ b/front/src/ether/contracts.js @@ -6,14 +6,14 @@ * See the file LICENSE for more information. */ -import * as ERC20PortalFacetArbitrumGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/ERC20PortalFacet.json"; -import * as ERC20PortalFacetOptimismGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/ERC20PortalFacet.json"; -import * as ERC20PortalFacetPolygonMumbai from "@cartesi/rollups/deployments/arbitrum_goerli/ERC20PortalFacet.json"; -import * as InputFacetArbitrumGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/InputFacet.json"; -import * as InputFacetOptimismGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/InputFacet.json"; -import * as InputFacetPolygonMumbai from "@cartesi/rollups/deployments/arbitrum_goerli/InputFacet.json"; -import * as ERC20PortalFacetGoerli from "@cartesi/rollups/deployments/goerli/ERC20PortalFacet.json"; -import * as InputFacetGoerli from "@cartesi/rollups/deployments/goerli/InputFacet.json"; +import * as ERC20PortalArbitrumGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/ERC20Portal.json"; +import * as ERC20PortalOptimismGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/ERC20Portal.json"; +import * as ERC20PortalPolygonMumbai from "@cartesi/rollups/deployments/arbitrum_goerli/ERC20Portal.json"; +import * as InputBoxArbitrumGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/InputBox.json"; +import * as InputBoxOptimismGoerli from "@cartesi/rollups/deployments/arbitrum_goerli/InputBox.json"; +import * as InputBoxPolygonMumbai from "@cartesi/rollups/deployments/arbitrum_goerli/InputBox.json"; +import * as ERC20PortalGoerli from "@cartesi/rollups/deployments/goerli/ERC20Portal.json"; +import * as InputBoxGoerli from "@cartesi/rollups/deployments/goerli/InputBox.json"; import * as CartesiTokenArbitrumGoerli from "@cartesi/token/deployments/arbitrum_goerli/CartesiToken.json"; import * as CartesiTokenArbitrumMainnet from "@cartesi/token/deployments/arbitrum_mainnet/CartesiToken.json"; import * as CartesiTokenGoerli from "@cartesi/token/deployments/goerli/CartesiToken.json"; @@ -30,16 +30,16 @@ import { contracts as contractsLocalhost } from "../abis/localhost.json"; export const CONTRACTS = { arbitrum_goerli: { CartesiToken: CartesiTokenArbitrumGoerli, - ERC20PortalFacet: ERC20PortalFacetArbitrumGoerli, - InputFacet: InputFacetArbitrumGoerli, + ERC20Portal: ERC20PortalArbitrumGoerli, + InputBox: InputBoxArbitrumGoerli, }, arbitrum_mainnet: { CartesiToken: CartesiTokenArbitrumMainnet, }, goerli: { CartesiToken: CartesiTokenGoerli, - ERC20PortalFacet: ERC20PortalFacetGoerli, - InputFacet: InputFacetGoerli, + ERC20Portal: ERC20PortalGoerli, + InputBox: InputBoxGoerli, SimpleFaucet: SimpleFaucetGoerli, }, localhost: Object.assign({}, contractsLocalhost, ultrachessLocalhost), @@ -48,20 +48,20 @@ export const CONTRACTS = { }, optimism_goerli: { CartesiToken: CartesiTokenOptimismGoerli, - ERC20PortalFacet: ERC20PortalFacetOptimismGoerli, - InputFacet: InputFacetOptimismGoerli, + ERC20Portal: ERC20PortalOptimismGoerli, + InputBox: InputBoxOptimismGoerli, }, optimism_mainnet: { CartesiToken: CartesiTokenOptimismMainnet, }, polygon_mainnet: { CartesiToken: CartesiTokenPolygonMainnet, - InputFacet: contractsLocalhost.InputFacet, - ERC20PortalFacet: contractsLocalhost.ERC20PortalFacet, + InputBox: contractsLocalhost.InputBox, + ERC20Portal: contractsLocalhost.ERC20Portal, }, polygon_mumbai: { CartesiToken: CartesiTokenPolygonMumbai, - ERC20PortalFacet: ERC20PortalFacetPolygonMumbai, - InputFacet: InputFacetPolygonMumbai, + ERC20Portal: ERC20PortalPolygonMumbai, + InputBox: InputBoxPolygonMumbai, }, }; diff --git a/front/yarn.lock b/front/yarn.lock index 3503175..00cb98f 100644 --- a/front/yarn.lock +++ b/front/yarn.lock @@ -515,14 +515,13 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@cartesi/rollups@^0.8.2": - version "0.8.2" - resolved "https://registry.npmjs.org/@cartesi/rollups/-/rollups-0.8.2.tgz" - integrity sha512-EiBJn2ZmkafCJSs7J02W/3xfhpThJrEx0S/+KQaEeC8r5O5JqIPHS9B34D2VcCevkLR+51VNv8O3O/aBl15Q4Q== +"@cartesi/rollups@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@cartesi/rollups/-/rollups-0.9.1.tgz#f6cd6294553b799016b721463160c65dadc6ff44" + integrity sha512-KTkvmRvWGKfecv2Vlnr6PmyNrVAtQBwzoAoqATWnZafOO06Pl/jSqVjyewLHsz+44tEst6lRsV8WDos4FeGlUA== dependencies: - "@cartesi/token" "^1.8.0" - "@cartesi/util" "^5.0.1" - "@openzeppelin/contracts" "^4.7.1" + "@cartesi/util" "^5.0.2" + "@openzeppelin/contracts" "4.8.0" "@cartesi/token@^1.8.0": version "1.8.0" @@ -531,9 +530,9 @@ dependencies: "@openzeppelin/contracts" "^2.5.0" -"@cartesi/util@^5.0.1": +"@cartesi/util@^5.0.2": version "5.0.2" - resolved "https://registry.npmjs.org/@cartesi/util/-/util-5.0.2.tgz" + resolved "https://registry.yarnpkg.com/@cartesi/util/-/util-5.0.2.tgz#dfe0ff88b1998b88eafc4089949c3df71e3246e1" integrity sha512-mIaOplU+RKkiW10JRpDBG8IG7lGKyXrkF6w4WHVZ2YKWze5I+mzJBaPALZLtJSuwb6GCqLZbB7NZx3A7iZyWkA== dependencies: "@openzeppelin/contracts" "3.2.1-solc-0.7" @@ -1738,16 +1737,16 @@ resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.2.1-solc-0.7.tgz" integrity sha512-VfKZE9L2HNaZVBR7l5yHbRmap3EiVw9F5iVXRRDdgfnA9vQ1yFanrs0VYmdo2VIXC+EsI9wPPYZY9Ic7/qDBdw== +"@openzeppelin/contracts@4.8.0": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.0.tgz#6854c37df205dd2c056bdfa1b853f5d732109109" + integrity sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw== + "@openzeppelin/contracts@^2.5.0": version "2.5.1" resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-2.5.1.tgz" integrity sha512-qIy6tLx8rtybEsIOAlrM4J/85s2q2nPkDqj/Rx46VakBZ0LwtFhXIVub96LXHczQX0vaqmAueDqNPXtbSXSaYQ== -"@openzeppelin/contracts@^4.7.1": - version "4.8.2" - resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.2.tgz" - integrity sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g== - "@parcel/watcher@^2.1.0": version "2.1.0" resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz" diff --git a/std-rootfs/Dockerfile b/std-rootfs/Dockerfile index 3352172..d4bef3e 100644 --- a/std-rootfs/Dockerfile +++ b/std-rootfs/Dockerfile @@ -1,8 +1,8 @@ # syntax=docker.io/docker/dockerfile:1.4 # layers for caching and versioning -FROM cartesi/toolchain:0.13.0 as toolchain -FROM cartesi/rootfs:0.16.0 as rootfs -FROM cartesi/server-manager:0.6.0 as server-manager +FROM cartesi/toolchain:0.14.0 as toolchain +FROM cartesi/rootfs:0.17.0 as rootfs +FROM cartesi/server-manager:0.7.0 as server-manager FROM rootfs as toolchain-python @@ -87,6 +87,7 @@ EOF WORKDIR /opt/cartesi/dapp COPY --from=dapp /opt/cartesi/dapp . + COPY build-dapp-fs.sh /usr/local/bin COPY default.json /opt/cartesi/ @@ -96,17 +97,29 @@ RUN build-dapp-fs.sh /opt/cartesi/default.json dapp.json dapp.ext2 # stage to build the initial cartesi machine FROM server-manager as server-stage +ARG NETWORK=localhost + WORKDIR /opt/cartesi/dapp # copy dapp ext2 from fs stage -COPY --from=fs-stage /opt/cartesi/dapp/dapp.ext2 . +COPY --from=fs /opt/cartesi/dapp/dapp.ext2 . # copy machine dependencies (rom, linux kernel, rootfs) -COPY --from=machine-core /opt/cartesi/share/* . +COPY --from=machine-core /opt/cartesi/share/rom.bin . +COPY --from=machine-core /opt/cartesi/share/linux.bin . +COPY --from=machine-core /opt/cartesi/share/rootfs.ext2 . + +# create var dir with correct permissions +USER root +RUN mkdir -p /var/opt/cartesi +RUN chown cartesi:cartesi /var/opt/cartesi +USER cartesi # build machine COPY build-machine.sh /usr/local/bin -RUN build-machine.sh /opt/cartesi/share/dapp-bin +RUN mkdir -p /var/opt/cartesi/machine-snapshots +RUN build-machine.sh /var/opt/cartesi/machine-snapshots/0_0 $NETWORK +RUN ln -s /var/opt/cartesi/machine-snapshots/0_0 /var/opt/cartesi/machine-snapshots/latest # switch back to server-manager workdir WORKDIR /opt/cartesi/bin @@ -118,7 +131,7 @@ FROM server-manager as console-stage WORKDIR /opt/cartesi/dapp # copy dapp ext2 from fs stage -COPY --from=fs-stage /opt/cartesi/dapp/dapp.ext2 . +COPY --from=fs /opt/cartesi/dapp/dapp.ext2 . # copy machine dependencies (rom, linux kernel, rootfs) COPY --from=machine-core /opt/cartesi/share/* . @@ -130,7 +143,7 @@ CMD ["run-machine-console.sh"] # stage to copy the stored machine FROM busybox as machine-stage -WORKDIR /opt/cartesi/share/dapp-bin -COPY --from=server-stage /opt/cartesi/share/dapp-bin . +WORKDIR /var/opt/cartesi/machine-snapshots +COPY --from=server /var/opt/cartesi/machine-snapshots . CMD ["xxd", "-c", "256", "-p", "hash"] diff --git a/std-rootfs/build-dapp-fs.sh b/std-rootfs/build-dapp-fs.sh index f2c9c41..f3ab6a6 100755 --- a/std-rootfs/build-dapp-fs.sh +++ b/std-rootfs/build-dapp-fs.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022 Cartesi Pte. Ltd. +# Copyright 2023 Cartesi Pte. Ltd. # # SPDX-License-Identifier: Apache-2.0 # Licensed under the Apache License, Version 2.0 (the "License"); you may not use diff --git a/std-rootfs/build-machine.sh b/std-rootfs/build-machine.sh index 37d7779..92cd1da 100755 --- a/std-rootfs/build-machine.sh +++ b/std-rootfs/build-machine.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022 Cartesi Pte. Ltd. +# Copyright 2023 Cartesi Pte. Ltd. # # SPDX-License-Identifier: Apache-2.0 # Licensed under the Apache License, Version 2.0 (the "License"); you may not use diff --git a/std-rootfs/dependencies b/std-rootfs/dependencies index 2ecb3c2..6222e9c 100644 --- a/std-rootfs/dependencies +++ b/std-rootfs/dependencies @@ -1,3 +1,3 @@ -rom.bin https://github.com/cartesi/machine-emulator-rom/releases/download/v0.15.0/rom-v0.15.0.bin -linux.bin https://github.com/cartesi/image-kernel/releases/download/v0.15.0/linux-5.15.63-ctsi-1.bin -rootfs.ext2 https://github.com/cartesi/image-rootfs/releases/download/v0.16.0/rootfs-v0.16.0.ext2 +rom.bin https://github.com/cartesi/machine-emulator-rom/releases/download/v0.16.0/rom-v0.16.0.bin +linux.bin https://github.com/cartesi/image-kernel/releases/download/v0.16.0/linux-5.15.63-ctsi-2.bin +rootfs.ext2 https://github.com/cartesi/image-rootfs/releases/download/v0.17.0/rootfs-v0.17.0.ext2 diff --git a/std-rootfs/run-machine-console.sh b/std-rootfs/run-machine-console.sh index bab0490..ae45688 100755 --- a/std-rootfs/run-machine-console.sh +++ b/std-rootfs/run-machine-console.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022 Cartesi Pte. Ltd. +# Copyright 2023 Cartesi Pte. Ltd. # # SPDX-License-Identifier: Apache-2.0 # Licensed under the Apache License, Version 2.0 (the "License"); you may not use diff --git a/std-rootfs/shasumfile b/std-rootfs/shasumfile index cf77676..358089b 100644 --- a/std-rootfs/shasumfile +++ b/std-rootfs/shasumfile @@ -1,3 +1,3 @@ -8d073e741493d637f6a99b9275118f208792702b *rom.bin -18f6c647ed2736f98b34880617a4b94db20fe2e2 *linux.bin -40bac513aebc945f1198b8a797b79ea6fa4101cf *rootfs.ext2 +f437c0f26e75760845eff64eeef525b79293d27f *rom.bin +a2697e86266ecb9790a23733e084b035b02cff9e *linux.bin +cc0af3d1db735051d078d1a381997655d128be0f *rootfs.ext2