From 1854dfba9991a25532de5f6a53cf50e66afb3c8b Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Wed, 13 Sep 2023 14:40:57 +0200 Subject: [PATCH] Redeployed on taiko test net after rebase --- deployments/taiko_test/Marketplace.json | 318 +++++++++--------- .../1f43413075cc2b565de996acf5469041.json | 80 +++++ 2 files changed, 231 insertions(+), 167 deletions(-) create mode 100644 deployments/taiko_test/solcInputs/1f43413075cc2b565de996acf5469041.json diff --git a/deployments/taiko_test/Marketplace.json b/deployments/taiko_test/Marketplace.json index 9f88468..8ab8699 100644 --- a/deployments/taiko_test/Marketplace.json +++ b/deployments/taiko_test/Marketplace.json @@ -1,5 +1,5 @@ { - "address": "0xDB2a8A1c8Df776F1C544a56a7734a865ad1C05e8", + "address": "0x948CF9291b77Bd7ad84781b9047129Addf1b894F", "abi": [ { "inputs": [ @@ -136,16 +136,10 @@ "type": "bytes32" }, { - "indexed": true, + "indexed": false, "internalType": "uint256", "name": "slotIndex", "type": "uint256" - }, - { - "indexed": false, - "internalType": "SlotId", - "name": "slotId", - "type": "bytes32" } ], "name": "SlotFilled", @@ -162,9 +156,9 @@ }, { "indexed": false, - "internalType": "SlotId", - "name": "slotId", - "type": "bytes32" + "internalType": "uint256", + "name": "slotIndex", + "type": "uint256" } ], "name": "SlotFreed", @@ -221,6 +215,12 @@ "internalType": "struct Ask", "name": "ask", "type": "tuple" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "expiry", + "type": "uint256" } ], "name": "StorageRequested", @@ -957,19 +957,19 @@ "type": "function" } ], - "transactionHash": "0x50307964c50857e9563ae3cc7922e34770763a2eb79c5defc9d396de7c5384e0", + "transactionHash": "0x20ae209f295c34cb2a1379c63c5d9a82b29a1730fb76f7d904a37aa3bb2cdbbb", "receipt": { "to": null, "from": "0xD40C3aED27Cb03CC671b66Fd52d81AE9d8702BE4", - "contractAddress": "0xDB2a8A1c8Df776F1C544a56a7734a865ad1C05e8", - "transactionIndex": 6, - "gasUsed": "3673077", + "contractAddress": "0x948CF9291b77Bd7ad84781b9047129Addf1b894F", + "transactionIndex": 1, + "gasUsed": "3504339", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x153ceefffd4c38d0400a8f0e3e80c81e4b4a6bac2731134a60d8fedfe46de85b", - "transactionHash": "0x50307964c50857e9563ae3cc7922e34770763a2eb79c5defc9d396de7c5384e0", + "blockHash": "0x5e123f5a919bef312d06824a618e0f06446a57f1777e6cd462da37fa7c246dcb", + "transactionHash": "0x20ae209f295c34cb2a1379c63c5d9a82b29a1730fb76f7d904a37aa3bb2cdbbb", "logs": [], - "blockNumber": 262545, - "cumulativeGasUsed": "5545143", + "blockNumber": 1857256, + "cumulativeGasUsed": "3632196", "status": 1, "byzantium": true }, @@ -989,11 +989,11 @@ } } ], - "numDeployments": 1, - "solcInputHash": "9671d4e1820229dcd69b349a99feb65b", - "metadata": "{\"compiler\":{\"version\":\"0.8.8+commit.dddeac2f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token_\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"repairRewardPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"maxNumberOfSlashes\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"slashCriterion\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"slashPercentage\",\"type\":\"uint8\"}],\"internalType\":\"struct CollateralConfig\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"downtime\",\"type\":\"uint8\"}],\"internalType\":\"struct ProofConfig\",\"name\":\"proofs\",\"type\":\"tuple\"}],\"internalType\":\"struct MarketplaceConfig\",\"name\":\"configuration\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"ProofSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"SlotFilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"SlotFreed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"}],\"name\":\"StorageRequested\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"repairRewardPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"maxNumberOfSlashes\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"slashCriterion\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"slashPercentage\",\"type\":\"uint8\"}],\"internalType\":\"struct CollateralConfig\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"downtime\",\"type\":\"uint8\"}],\"internalType\":\"struct ProofConfig\",\"name\":\"proofs\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"fillSlot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"freeSlot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"getActiveSlot\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"cid\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"totalChunks\",\"type\":\"uint64\"}],\"internalType\":\"struct Erasure\",\"name\":\"erasure\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"u\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"internalType\":\"struct PoR\",\"name\":\"por\",\"type\":\"tuple\"}],\"internalType\":\"struct Content\",\"name\":\"content\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct Request\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"internalType\":\"struct Marketplace.ActiveSlot\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getChallenge\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"getHost\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getPointer\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"getRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"cid\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"totalChunks\",\"type\":\"uint64\"}],\"internalType\":\"struct Erasure\",\"name\":\"erasure\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"u\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"internalType\":\"struct PoR\",\"name\":\"por\",\"type\":\"tuple\"}],\"internalType\":\"struct Content\",\"name\":\"content\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct Request\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"isProofRequired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"},{\"internalType\":\"Periods.Period\",\"name\":\"period\",\"type\":\"uint256\"}],\"name\":\"markProofAsMissing\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"missingProofs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"myRequests\",\"outputs\":[{\"internalType\":\"RequestId[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mySlots\",\"outputs\":[{\"internalType\":\"SlotId[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"requestEnd\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"requestState\",\"outputs\":[{\"internalType\":\"enum RequestState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"cid\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"totalChunks\",\"type\":\"uint64\"}],\"internalType\":\"struct Erasure\",\"name\":\"erasure\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"u\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"internalType\":\"struct PoR\",\"name\":\"por\",\"type\":\"tuple\"}],\"internalType\":\"struct Content\",\"name\":\"content\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct Request\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"requestStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"slotState\",\"outputs\":[{\"internalType\":\"enum SlotState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"submitProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"willProofBeRequired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"withdrawFunds(bytes32)\":{\"details\":\"Request must be expired, must be in RequestState.New, and the transaction must originate from the depositer address.\",\"params\":{\"requestId\":\"the id of the request\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"withdrawFunds(bytes32)\":{\"notice\":\"Withdraws storage request funds back to the client that deposited them.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Marketplace.sol\":\"Marketplace\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"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/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xc3ff3f5c4584e1d9a483ad7ced51ab64523201f4e3d3c65293e4ca8aeb77a961\",\"license\":\"MIT\"},\"contracts/Configuration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nstruct MarketplaceConfig {\\n CollateralConfig collateral;\\n ProofConfig proofs;\\n}\\n\\nstruct CollateralConfig {\\n /// @dev percentage of remaining collateral slot after it has been freed\\n /// (equivalent to `collateral - (collateral*maxNumberOfSlashes*slashPercentage)/100`)\\n /// TODO: to be aligned more closely with actual cost of repair once bandwidth incentives are known,\\n /// see https://github.com/codex-storage/codex-contracts-eth/pull/47#issuecomment-1465511949.\\n uint8 repairRewardPercentage;\\n\\n uint8 maxNumberOfSlashes; // frees slot when the number of slashing reaches this value\\n uint16 slashCriterion; // amount of proofs missed that lead to slashing\\n uint8 slashPercentage; // percentage of the collateral that is slashed\\n}\\n\\nstruct ProofConfig {\\n uint256 period; // proofs requirements are calculated per period (in seconds)\\n uint256 timeout; // mark proofs as missing before the timeout (in seconds)\\n uint8 downtime; // ignore this much recent blocks for proof requirements\\n}\\n\",\"keccak256\":\"0x355b9cd03f5ffadd52cb07c64934bb823bfebced18f4cec9e714326dfee152fc\",\"license\":\"MIT\"},\"contracts/Marketplace.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"./Configuration.sol\\\";\\nimport \\\"./Requests.sol\\\";\\nimport \\\"./Proofs.sol\\\";\\nimport \\\"./StateRetrieval.sol\\\";\\n\\ncontract Marketplace is Proofs, StateRetrieval {\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using Requests for Request;\\n\\n IERC20 public immutable token;\\n MarketplaceConfig public config;\\n\\n MarketplaceFunds private _funds;\\n mapping(RequestId => Request) private _requests;\\n mapping(RequestId => RequestContext) private _requestContexts;\\n mapping(SlotId => Slot) internal _slots;\\n\\n struct RequestContext {\\n RequestState state;\\n uint256 slotsFilled;\\n uint256 startedAt;\\n uint256 endsAt;\\n }\\n\\n struct Slot {\\n SlotState state;\\n RequestId requestId;\\n uint256 slotIndex;\\n\\n /// @notice Tracks the current amount of host's collateral that is to be payed out at the end of Slot's lifespan.\\n /// @dev When Slot is filled, the collateral is collected in amount of request.ask.collateral\\n /// @dev When Host is slashed for missing a proof the slashed amount is reflected in this variable\\n uint256 currentCollateral;\\n address host;\\n }\\n\\n struct ActiveSlot {\\n Request request;\\n uint256 slotIndex;\\n }\\n\\n constructor(\\n IERC20 token_,\\n MarketplaceConfig memory configuration\\n ) Proofs(configuration.proofs) marketplaceInvariant {\\n token = token_;\\n\\n require(configuration.collateral.repairRewardPercentage <= 100, \\\"Must be less than 100\\\");\\n require(configuration.collateral.slashPercentage <= 100, \\\"Must be less than 100\\\");\\n require(configuration.collateral.maxNumberOfSlashes * configuration.collateral.slashPercentage <= 100, \\\"Total slash percentage must be less then 100\\\");\\n config = configuration;\\n }\\n\\n function requestStorage(\\n Request calldata request\\n ) public marketplaceInvariant {\\n require(request.client == msg.sender, \\\"Invalid client address\\\");\\n\\n RequestId id = request.id();\\n require(_requests[id].client == address(0), \\\"Request already exists\\\");\\n\\n _requests[id] = request;\\n _requestContexts[id].endsAt = block.timestamp + request.ask.duration;\\n\\n _addToMyRequests(request.client, id);\\n\\n uint256 amount = request.price();\\n _funds.received += amount;\\n _funds.balance += amount;\\n _transferFrom(msg.sender, amount);\\n\\n emit StorageRequested(id, request.ask);\\n }\\n\\n function fillSlot(\\n RequestId requestId,\\n uint256 slotIndex,\\n bytes calldata proof\\n ) public requestIsKnown(requestId) {\\n Request storage request = _requests[requestId];\\n require(slotIndex < request.ask.slots, \\\"Invalid slot\\\");\\n\\n SlotId slotId = Requests.slotId(requestId, slotIndex);\\n Slot storage slot = _slots[slotId];\\n slot.requestId = requestId;\\n slot.slotIndex = slotIndex;\\n\\n require(slotState(slotId) == SlotState.Free, \\\"Slot is not free\\\");\\n\\n _startRequiringProofs(slotId, request.ask.proofProbability);\\n submitProof(slotId, proof);\\n\\n slot.host = msg.sender;\\n slot.state = SlotState.Filled;\\n RequestContext storage context = _requestContexts[requestId];\\n context.slotsFilled += 1;\\n\\n // Collect collateral\\n uint256 collateralAmount = request.ask.collateral;\\n _transferFrom(msg.sender, collateralAmount);\\n _funds.received += collateralAmount;\\n _funds.balance += collateralAmount;\\n slot.currentCollateral = collateralAmount;\\n\\n _addToMySlots(slot.host, slotId);\\n\\n emit SlotFilled(requestId, slotIndex, slotId);\\n if (context.slotsFilled == request.ask.slots) {\\n context.state = RequestState.Started;\\n context.startedAt = block.timestamp;\\n emit RequestFulfilled(requestId);\\n }\\n }\\n\\n function freeSlot(SlotId slotId) public slotIsNotFree(slotId) {\\n Slot storage slot = _slots[slotId];\\n require(slot.host == msg.sender, \\\"Slot filled by other host\\\");\\n SlotState state = slotState(slotId);\\n require(state != SlotState.Paid, \\\"Already paid\\\");\\n\\n if (state == SlotState.Finished) {\\n _payoutSlot(slot.requestId, slotId);\\n } else if (state == SlotState.Failed) {\\n _removeFromMySlots(msg.sender, slotId);\\n } else if (state == SlotState.Filled) {\\n _forciblyFreeSlot(slotId);\\n }\\n }\\n\\n function markProofAsMissing(SlotId slotId, Period period) public {\\n require(slotState(slotId) == SlotState.Filled, \\\"Slot not accepting proofs\\\");\\n _markProofAsMissing(slotId, period);\\n Slot storage slot = _slots[slotId];\\n Request storage request = _requests[slot.requestId];\\n\\n if (missingProofs(slotId) % config.collateral.slashCriterion == 0) {\\n uint256 slashedAmount = (request.ask.collateral * config.collateral.slashPercentage) / 100;\\n slot.currentCollateral -= slashedAmount;\\n _funds.slashed += slashedAmount;\\n _funds.balance -= slashedAmount;\\n\\n if (missingProofs(slotId) / config.collateral.slashCriterion >= config.collateral.maxNumberOfSlashes) {\\n // When the number of slashings is at or above the allowed amount,\\n // free the slot.\\n _forciblyFreeSlot(slotId);\\n }\\n }\\n }\\n\\n function _forciblyFreeSlot(SlotId slotId) internal marketplaceInvariant {\\n Slot storage slot = _slots[slotId];\\n RequestId requestId = slot.requestId;\\n RequestContext storage context = _requestContexts[requestId];\\n\\n _removeFromMySlots(slot.host, slotId);\\n\\n delete _slots[slotId];\\n context.slotsFilled -= 1;\\n emit SlotFreed(requestId, slotId);\\n resetMissingProofs(slotId);\\n\\n Request storage request = _requests[requestId];\\n uint256 slotsLost = request.ask.slots - context.slotsFilled;\\n if (\\n slotsLost > request.ask.maxSlotLoss &&\\n context.state == RequestState.Started\\n ) {\\n context.state = RequestState.Failed;\\n context.endsAt = block.timestamp - 1;\\n emit RequestFailed(requestId);\\n\\n // TODO: send client remaining funds\\n }\\n }\\n\\n function _payoutSlot(\\n RequestId requestId,\\n SlotId slotId\\n ) private requestIsKnown(requestId) marketplaceInvariant {\\n RequestContext storage context = _requestContexts[requestId];\\n Request storage request = _requests[requestId];\\n context.state = RequestState.Finished;\\n _removeFromMyRequests(request.client, requestId);\\n Slot storage slot = _slots[slotId];\\n\\n _removeFromMySlots(slot.host, slotId);\\n\\n uint256 amount = _requests[requestId].pricePerSlot() + slot.currentCollateral;\\n _funds.sent += amount;\\n _funds.balance -= amount;\\n slot.state = SlotState.Paid;\\n require(token.transfer(slot.host, amount), \\\"Payment failed\\\");\\n }\\n\\n /// @notice Withdraws storage request funds back to the client that deposited them.\\n /// @dev Request must be expired, must be in RequestState.New, and the transaction must originate from the depositer address.\\n /// @param requestId the id of the request\\n function withdrawFunds(RequestId requestId) public marketplaceInvariant {\\n Request storage request = _requests[requestId];\\n require(block.timestamp > request.expiry, \\\"Request not yet timed out\\\");\\n require(request.client == msg.sender, \\\"Invalid client address\\\");\\n RequestContext storage context = _requestContexts[requestId];\\n require(context.state == RequestState.New, \\\"Invalid state\\\");\\n\\n // Update request state to Cancelled. Handle in the withdraw transaction\\n // as there needs to be someone to pay for the gas to update the state\\n context.state = RequestState.Cancelled;\\n _removeFromMyRequests(request.client, requestId);\\n\\n emit RequestCancelled(requestId);\\n\\n // TODO: To be changed once we start paying out hosts for the time they\\n // fill a slot. The amount that we paid to hosts will then have to be\\n // deducted from the price.\\n uint256 amount = request.price();\\n _funds.sent += amount;\\n _funds.balance -= amount;\\n require(token.transfer(msg.sender, amount), \\\"Withdraw failed\\\");\\n }\\n\\n function getActiveSlot(SlotId slotId)\\n public\\n view\\n slotIsNotFree(slotId)\\n returns (ActiveSlot memory)\\n {\\n Slot storage slot = _slots[slotId];\\n ActiveSlot memory activeSlot;\\n activeSlot.request = _requests[slot.requestId];\\n activeSlot.slotIndex = slot.slotIndex;\\n return activeSlot;\\n }\\n\\n modifier requestIsKnown(RequestId requestId) {\\n require(_requests[requestId].client != address(0), \\\"Unknown request\\\");\\n _;\\n }\\n\\n function getRequest(\\n RequestId requestId\\n ) public view requestIsKnown(requestId) returns (Request memory) {\\n return _requests[requestId];\\n }\\n\\n modifier slotIsNotFree(SlotId slotId) {\\n require(_slots[slotId].state != SlotState.Free, \\\"Slot is free\\\");\\n _;\\n }\\n\\n function requestEnd(RequestId requestId) public view returns (uint256) {\\n uint256 end = _requestContexts[requestId].endsAt;\\n RequestState state = requestState(requestId);\\n if (state == RequestState.New || state == RequestState.Started) {\\n return end;\\n } else {\\n return Math.min(end, block.timestamp - 1);\\n }\\n }\\n\\n function getHost(SlotId slotId) public view returns (address) {\\n return _slots[slotId].host;\\n }\\n\\n function requestState(\\n RequestId requestId\\n ) public view requestIsKnown(requestId) returns (RequestState) {\\n RequestContext storage context = _requestContexts[requestId];\\n if (\\n context.state == RequestState.New &&\\n block.timestamp > _requests[requestId].expiry\\n ) {\\n return RequestState.Cancelled;\\n } else if (\\n context.state == RequestState.Started && block.timestamp > context.endsAt\\n ) {\\n return RequestState.Finished;\\n } else {\\n return context.state;\\n }\\n }\\n\\n function slotState(SlotId slotId) public view override returns (SlotState) {\\n Slot storage slot = _slots[slotId];\\n if (RequestId.unwrap(slot.requestId) == 0) {\\n return SlotState.Free;\\n }\\n RequestState reqState = requestState(slot.requestId);\\n if (slot.state == SlotState.Paid) {\\n return SlotState.Paid;\\n }\\n if (reqState == RequestState.Cancelled) {\\n return SlotState.Finished;\\n }\\n if (reqState == RequestState.Finished) {\\n return SlotState.Finished;\\n }\\n if (reqState == RequestState.Failed) {\\n return SlotState.Failed;\\n }\\n return slot.state;\\n }\\n\\n function _transferFrom(address sender, uint256 amount) internal {\\n address receiver = address(this);\\n require(token.transferFrom(sender, receiver, amount), \\\"Transfer failed\\\");\\n }\\n\\n event StorageRequested(RequestId requestId, Ask ask);\\n event RequestFulfilled(RequestId indexed requestId);\\n event RequestFailed(RequestId indexed requestId);\\n event SlotFilled(\\n RequestId indexed requestId,\\n uint256 indexed slotIndex,\\n SlotId slotId\\n );\\n event SlotFreed(RequestId indexed requestId, SlotId slotId);\\n event RequestCancelled(RequestId indexed requestId);\\n\\n modifier marketplaceInvariant() {\\n MarketplaceFunds memory oldFunds = _funds;\\n _;\\n assert(_funds.received >= oldFunds.received);\\n assert(_funds.sent >= oldFunds.sent);\\n assert(_funds.slashed >= oldFunds.slashed);\\n assert(_funds.received == _funds.balance + _funds.sent + _funds.slashed);\\n }\\n\\n struct MarketplaceFunds {\\n uint256 balance;\\n uint256 received;\\n uint256 sent;\\n uint256 slashed;\\n }\\n}\\n\",\"keccak256\":\"0x9671994a8cd7f9e1f7b56585145f0def1053035192b14136a4fc415366a477bb\",\"license\":\"MIT\"},\"contracts/Periods.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\ncontract Periods {\\n type Period is uint256;\\n\\n uint256 internal immutable _secondsPerPeriod;\\n\\n constructor(uint256 secondsPerPeriod) {\\n _secondsPerPeriod = secondsPerPeriod;\\n }\\n\\n function _periodOf(uint256 timestamp) internal view returns (Period) {\\n return Period.wrap(timestamp / _secondsPerPeriod);\\n }\\n\\n function _blockPeriod() internal view returns (Period) {\\n return _periodOf(block.timestamp);\\n }\\n\\n function _nextPeriod(Period period) internal pure returns (Period) {\\n return Period.wrap(Period.unwrap(period) + 1);\\n }\\n\\n function _periodStart(Period period) internal view returns (uint256) {\\n return Period.unwrap(period) * _secondsPerPeriod;\\n }\\n\\n function _periodEnd(Period period) internal view returns (uint256) {\\n return _periodStart(_nextPeriod(period));\\n }\\n\\n function _isBefore(Period a, Period b) internal pure returns (bool) {\\n return Period.unwrap(a) < Period.unwrap(b);\\n }\\n\\n function _isAfter(Period a, Period b) internal pure returns (bool) {\\n return _isBefore(b, a);\\n }\\n}\\n\",\"keccak256\":\"0xf5c816a69a705fd84bd3e43490ea32e8cc5bec05363b7c2deb32665519d0bfe2\",\"license\":\"MIT\"},\"contracts/Proofs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"./Configuration.sol\\\";\\nimport \\\"./Requests.sol\\\";\\nimport \\\"./Periods.sol\\\";\\n\\nabstract contract Proofs is Periods {\\n ProofConfig private _config;\\n\\n constructor(ProofConfig memory config) Periods(config.period) {\\n require(block.number > 256, \\\"Insufficient block height\\\");\\n _config = config;\\n }\\n\\n mapping(SlotId => uint256) private _slotStarts;\\n mapping(SlotId => uint256) private _probabilities;\\n mapping(SlotId => uint256) private _missed;\\n mapping(SlotId => mapping(Period => bool)) private _received;\\n mapping(SlotId => mapping(Period => bool)) private _missing;\\n\\n function slotState(SlotId id) public view virtual returns (SlotState);\\n\\n function missingProofs(SlotId slotId) public view returns (uint256) {\\n return _missed[slotId];\\n }\\n\\n function resetMissingProofs(SlotId slotId) internal {\\n _missed[slotId] = 0;\\n }\\n\\n function _startRequiringProofs(SlotId id, uint256 probability) internal {\\n _slotStarts[id] = block.timestamp;\\n _probabilities[id] = probability;\\n }\\n\\n function _getPointer(SlotId id, Period period) internal view returns (uint8) {\\n uint256 blockNumber = block.number % 256;\\n uint256 periodNumber = Period.unwrap(period) % 256;\\n uint256 idOffset = uint256(SlotId.unwrap(id)) % 256;\\n uint256 pointer = (blockNumber + periodNumber + idOffset) % 256;\\n return uint8(pointer);\\n }\\n\\n function getPointer(SlotId id) public view returns (uint8) {\\n return _getPointer(id, _blockPeriod());\\n }\\n\\n function _getChallenge(uint8 pointer) internal view returns (bytes32) {\\n bytes32 hash = blockhash(block.number - 1 - pointer);\\n assert(uint256(hash) != 0);\\n return keccak256(abi.encode(hash));\\n }\\n\\n function _getChallenge(\\n SlotId id,\\n Period period\\n ) internal view returns (bytes32) {\\n return _getChallenge(_getPointer(id, period));\\n }\\n\\n function getChallenge(SlotId id) public view returns (bytes32) {\\n return _getChallenge(id, _blockPeriod());\\n }\\n\\n function _getProofRequirement(\\n SlotId id,\\n Period period\\n ) internal view returns (bool isRequired, uint8 pointer) {\\n SlotState state = slotState(id);\\n Period start = _periodOf(_slotStarts[id]);\\n if (state != SlotState.Filled || !_isAfter(period, start)) {\\n return (false, 0);\\n }\\n pointer = _getPointer(id, period);\\n bytes32 challenge = _getChallenge(pointer);\\n uint256 probability = (_probabilities[id] * (256 - _config.downtime)) / 256;\\n isRequired = probability == 0 || uint256(challenge) % probability == 0;\\n }\\n\\n function _isProofRequired(\\n SlotId id,\\n Period period\\n ) internal view returns (bool) {\\n bool isRequired;\\n uint8 pointer;\\n (isRequired, pointer) = _getProofRequirement(id, period);\\n return isRequired && pointer >= _config.downtime;\\n }\\n\\n function isProofRequired(SlotId id) public view returns (bool) {\\n return _isProofRequired(id, _blockPeriod());\\n }\\n\\n function willProofBeRequired(SlotId id) public view returns (bool) {\\n bool isRequired;\\n uint8 pointer;\\n (isRequired, pointer) = _getProofRequirement(id, _blockPeriod());\\n return isRequired && pointer < _config.downtime;\\n }\\n\\n function submitProof(SlotId id, bytes calldata proof) public {\\n require(proof.length > 0, \\\"Invalid proof\\\"); // TODO: replace by actual check\\n require(!_received[id][_blockPeriod()], \\\"Proof already submitted\\\");\\n _received[id][_blockPeriod()] = true;\\n emit ProofSubmitted(id, proof);\\n }\\n\\n function _markProofAsMissing(SlotId id, Period missedPeriod) internal {\\n uint256 end = _periodEnd(missedPeriod);\\n require(end < block.timestamp, \\\"Period has not ended yet\\\");\\n require(block.timestamp < end + _config.timeout, \\\"Validation timed out\\\");\\n require(!_received[id][missedPeriod], \\\"Proof was submitted, not missing\\\");\\n require(_isProofRequired(id, missedPeriod), \\\"Proof was not required\\\");\\n require(!_missing[id][missedPeriod], \\\"Proof already marked as missing\\\");\\n _missing[id][missedPeriod] = true;\\n _missed[id] += 1;\\n }\\n\\n event ProofSubmitted(SlotId id, bytes proof);\\n}\\n\",\"keccak256\":\"0xd94bb254cb3c3b4c45ab2376975973b16e77bf1a811c3e1251aba1e7caa01f50\",\"license\":\"MIT\"},\"contracts/Requests.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\ntype RequestId is bytes32;\\ntype SlotId is bytes32;\\n\\nstruct Request {\\n address client;\\n Ask ask;\\n Content content;\\n uint256 expiry; // timestamp as seconds since unix epoch at which this request expires\\n bytes32 nonce; // random nonce to differentiate between similar requests\\n}\\n\\nstruct Ask {\\n uint64 slots; // the number of requested slots\\n uint256 slotSize; // amount of storage per slot (in number of bytes)\\n uint256 duration; // how long content should be stored (in seconds)\\n uint256 proofProbability; // how often storage proofs are required\\n uint256 reward; // amount of tokens paid per second per slot to hosts\\n uint256 collateral; // amount of tokens required to be deposited by the hosts in order to fill the slot\\n uint64 maxSlotLoss; // Max slots that can be lost without data considered to be lost\\n}\\n\\nstruct Content {\\n string cid; // content id (if part of a larger set, the chunk cid)\\n Erasure erasure; // Erasure coding attributes\\n PoR por; // Proof of Retrievability parameters\\n}\\n\\nstruct Erasure {\\n uint64 totalChunks; // the total number of chunks in the larger data set\\n}\\n\\nstruct PoR {\\n bytes u; // parameters u_1..u_s\\n bytes publicKey; // public key\\n bytes name; // random name\\n}\\n\\nenum RequestState {\\n New, // [default] waiting to fill slots\\n Started, // all slots filled, accepting regular proofs\\n Cancelled, // not enough slots filled before expiry\\n Finished, // successfully completed\\n Failed // too many nodes have failed to provide proofs, data lost\\n}\\n\\nenum SlotState {\\n Free, // [default] not filled yet, or host has vacated the slot\\n Filled, // host has filled slot\\n Finished, // successfully completed\\n Failed, // the request has failed\\n Paid // host has been paid\\n}\\n\\nlibrary Requests {\\n function id(Request memory request) internal pure returns (RequestId) {\\n return RequestId.wrap(keccak256(abi.encode(request)));\\n }\\n\\n function slotId(\\n RequestId requestId,\\n uint256 slotIndex\\n ) internal pure returns (SlotId) {\\n return SlotId.wrap(keccak256(abi.encode(requestId, slotIndex)));\\n }\\n\\n function toRequestIds(\\n bytes32[] memory ids\\n ) internal pure returns (RequestId[] memory result) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := ids\\n }\\n }\\n\\n function toSlotIds(\\n bytes32[] memory ids\\n ) internal pure returns (SlotId[] memory result) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := ids\\n }\\n }\\n\\n function pricePerSlot(\\n Request memory request\\n ) internal pure returns (uint256) {\\n return request.ask.duration * request.ask.reward;\\n }\\n\\n function price(Request memory request) internal pure returns (uint256) {\\n return request.ask.slots * pricePerSlot(request);\\n }\\n}\\n\",\"keccak256\":\"0x84d4ed812857885c70457625e815abf47e53b41ef4d06d5decc9fa13d82ed45c\",\"license\":\"MIT\"},\"contracts/StateRetrieval.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"./Requests.sol\\\";\\n\\ncontract StateRetrieval {\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using Requests for bytes32[];\\n\\n mapping(address => EnumerableSet.Bytes32Set) private _requestsPerClient;\\n mapping(address => EnumerableSet.Bytes32Set) private _slotsPerHost;\\n\\n function myRequests() public view returns (RequestId[] memory) {\\n return _requestsPerClient[msg.sender].values().toRequestIds();\\n }\\n\\n function mySlots() public view returns (SlotId[] memory) {\\n return _slotsPerHost[msg.sender].values().toSlotIds();\\n }\\n\\n function _hasSlots(address host) internal view returns (bool) {\\n return _slotsPerHost[host].length() > 0;\\n }\\n\\n function _addToMyRequests(address client, RequestId requestId) internal {\\n _requestsPerClient[client].add(RequestId.unwrap(requestId));\\n }\\n\\n function _addToMySlots(address host, SlotId slotId) internal {\\n _slotsPerHost[host].add(SlotId.unwrap(slotId));\\n }\\n\\n function _removeFromMyRequests(address client, RequestId requestId) internal {\\n _requestsPerClient[client].remove(RequestId.unwrap(requestId));\\n }\\n\\n function _removeFromMySlots(address host, SlotId slotId) internal {\\n _slotsPerHost[host].remove(SlotId.unwrap(slotId));\\n }\\n}\\n\",\"keccak256\":\"0xe29275c3ff31874cac3b8ecf67c59502e9fdefb956142278c58ee3aa956801fd\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620043ee380380620043ee833981016040819052620000349162000439565b602081015180516080526101004311620000955760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420626c6f636b206865696768740000000000000060448201526064015b60405180910390fd5b80516000556020808201516001556040918201516002805460ff191660ff9283161790558251608081018452600e548152600f54928101929092526010549282019290925260115460608083019190915284901b6001600160601b03191660a05282515190916064911611156200014f5760405162461bcd60e51b815260206004820152601560248201527f4d757374206265206c657373207468616e20313030000000000000000000000060448201526064016200008c565b606482600001516060015160ff161115620001ad5760405162461bcd60e51b815260206004820152601560248201527f4d757374206265206c657373207468616e20313030000000000000000000000060448201526064016200008c565b81516060810151602090910151606491620001c8916200052b565b60ff161115620002305760405162461bcd60e51b815260206004820152602c60248201527f546f74616c20736c6173682070657263656e74616765206d757374206265206c60448201526b0657373207468656e203130360a41b60648201526084016200008c565b81518051600a805460208085015160408087015160609097015160ff9081166401000000000260ff60201b1961ffff90991662010000029890981664ffffff0000199382166101000261ffff199096169782169790971794909417919091169490941794909417909155828501518051600b5580840151600c5590910151600d80549190921660ff1991909116179055810151600f541015620002d757620002d762000557565b60408101516010541015620002f057620002f062000557565b6060810151601154101562000309576200030962000557565b601154601054600e546200031e91906200056d565b6200032a91906200056d565b600f54146200033d576200033d62000557565b50505062000588565b604080519081016001600160401b03811182821017156200037757634e487b7160e01b600052604160045260246000fd5b60405290565b604051608081016001600160401b03811182821017156200037757634e487b7160e01b600052604160045260246000fd5b805160ff81168114620003c057600080fd5b919050565b600060608284031215620003d857600080fd5b604051606081016001600160401b03811182821017156200040957634e487b7160e01b600052604160045260246000fd5b806040525080915082518152602083015160208201526200042d60408401620003ae565b60408201525092915050565b6000808284036101008112156200044f57600080fd5b83516001600160a01b03811681146200046757600080fd5b9250601f190160e08112156200047c57600080fd5b6200048662000346565b60808212156200049557600080fd5b6200049f6200037d565b9150620004af60208601620003ae565b8252620004bf60408601620003ae565b6020830152606085015161ffff81168114620004da57600080fd5b6040830152620004ed60808601620003ae565b6060830152818152620005048660a08701620003c5565b602082015280925050509250929050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168160ff04811182151516156200054f576200054f62000515565b029392505050565b634e487b7160e01b600052600160045260246000fd5b6000821982111562000583576200058362000515565b500190565b60805160a05160601c613e21620005cd60003960008181610442015281816113730152818161238c01526129c2015260008181612c770152612d780152613e216000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80636e2b54ee116100d8578063b396dc791161008c578063f752196b11610066578063f752196b146103fd578063fb1e61ca1461041d578063fc0c546a1461043d57600080fd5b8063b396dc79146103b7578063be5cdc48146103d7578063c0cc4add146103ea57600080fd5b80639777b72c116100bd5780639777b72c14610379578063a29c29a414610381578063a3a0807e1461039457600080fd5b80636e2b54ee146102a157806379502c55146102b457600080fd5b80634641dce61161012f5780636368a471116101145780636368a47114610237578063645116d81461024a5780636b00c8cf1461025d57600080fd5b80634641dce6146101fd5780635da738351461022257600080fd5b806308695fcd1161016057806308695fcd146101c25780630eb6c86f146101d7578063458d2bf1146101ea57600080fd5b806302fa8e651461017c57806305b90773146101a2575b600080fd5b61018f61018a366004612fef565b610464565b6040519081526020015b60405180910390f35b6101b56101b0366004612fef565b6104db565b604051610199919061303f565b6101d56101d0366004613052565b6105cd565b005b6101d56101e5366004613074565b610754565b61018f6101f8366004612fef565b6109bf565b61021061020b366004612fef565b6109d8565b60405160ff9091168152602001610199565b61022a6109eb565b60405161019991906130b0565b6101d5610245366004613136565b610a12565b6101d5610258366004613189565b610d0b565b61028961026b366004612fef565b6000908152601460205260409020600401546001600160a01b031690565b6040516001600160a01b039091168152602001610199565b6101d56102af366004612fef565b610e4e565b60408051608081018252600a5460ff80821683526101008204811660208085019190915261ffff6201000084041684860152640100000000909204811660608085019190915284519081018552600b548152600c5492810192909252600d5416928101929092526103229182565b60408051835160ff90811682526020808601518216818401528584015161ffff1683850152606095860151821695830195909552835160808301529383015160a082015291015190911660c082015260e001610199565b61022a61145c565b6101d561038f366004612fef565b61147b565b6103a76103a2366004612fef565b61162a565b6040519015158152602001610199565b6103ca6103c5366004612fef565b61165f565b6040516101999190613351565b6101b56103e5366004612fef565b611a2f565b6103a76103f8366004612fef565b611aff565b61018f61040b366004612fef565b60009081526005602052604090205490565b61043061042b366004612fef565b611b12565b6040516101999190613383565b6102897f000000000000000000000000000000000000000000000000000000000000000081565b60008181526013602052604081206003015481610480846104db565b9050600081600481111561049657610496613008565b14806104b3575060018160048111156104b1576104b1613008565b145b156104bf575092915050565b6104d3826104ce6001426133ac565b611eab565b949350505050565b60008181526012602052604081205482906001600160a01b03166105385760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b60448201526064015b60405180910390fd5b600083815260136020526040812090815460ff16600481111561055d5761055d613008565b14801561057a57506000848152601260205260409020600d015442115b156105895760029250506105c7565b6001815460ff1660048111156105a1576105a1613008565b1480156105b15750806003015442115b156105c05760039250506105c7565b5460ff1691505b50919050565b60016105d883611a2f565b60048111156105e9576105e9613008565b146106365760405162461bcd60e51b815260206004820152601960248201527f536c6f74206e6f7420616363657074696e672070726f6f667300000000000000604482015260640161052f565b6106408282611ec3565b6000828152601460209081526040808320600181015484526012909252909120600a5461ffff62010000909104166106848560009081526005602052604090205490565b61068e91906133d9565b61074e57600a5460068201546000916064916106b591640100000000900460ff16906133ed565b6106bf919061340c565b9050808360030160008282546106d591906133ac565b9091555050601180548291906000906106ef908490613420565b9091555050600e80548291906000906107099084906133ac565b9091555050600a54600086815260056020526040902054610100820460ff169162010000900461ffff169061073e919061340c565b1061074c5761074c856120f0565b505b50505050565b60408051608081018252600e548152600f546020808301919091526010549282019290925260115460608201529033906107909084018461344d565b6001600160a01b0316146107e65760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b60006107f96107f484613703565b6122c8565b6000818152601260205260409020549091506001600160a01b0316156108615760405162461bcd60e51b815260206004820152601660248201527f5265717565737420616c72656164792065786973747300000000000000000000604482015260640161052f565b6000818152601260205260409020839061087b8282613bbf565b5061088c9050606084013542613420565b6000828152601360209081526040909120600301919091556108ba906108b49085018561344d565b826122f8565b60006108cd6108c885613703565b61231f565b905080600e60010160008282546108e49190613420565b9091555050600e80548291906000906108fe908490613420565b9091555061090e90503382612344565b7ff6285655f5f3c277c1bfd91fe7bf7c48929cce5114cf4e3892ebaf7f7af53de98285602001604051610942929190613cb7565b60405180910390a150506020810151600f54101561096257610962613d2e565b6040810151601054101561097857610978613d2e565b6060810151601154101561098e5761098e613d2e565b601154601054600e546109a19190613420565b6109ab9190613420565b600f54146109bb576109bb613d2e565b5050565b60006109d2826109cd612456565b612461565b92915050565b60006109d2826109e6612456565b612475565b336000908152600960205260409020606090610a0d90610a0a906124d5565b90565b905090565b60008481526012602052604090205484906001600160a01b0316610a6a5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000858152601260205260409020600181015467ffffffffffffffff168510610ad55760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420736c6f740000000000000000000000000000000000000000604482015260640161052f565b604080516020808201899052818301889052825180830384018152606090920190925280519101206000906000818152601460205260408120600181018a905560028101899055919250610b2883611a2f565b6004811115610b3957610b39613008565b14610b865760405162461bcd60e51b815260206004820152601060248201527f536c6f74206973206e6f74206672656500000000000000000000000000000000604482015260640161052f565b60048084015460008481526003602090815260408083204290559390529190912055610bb3828787610d0b565b60048101805473ffffffffffffffffffffffffffffffffffffffff191633179055805460ff191660019081178255600089815260136020526040812080830180549193929091610c04908490613420565b90915550506006840154610c183382612344565b80600e6001016000828254610c2d9190613420565b9091555050600e8054829190600090610c47908490613420565b9091555050600383018190556004830154610c6b906001600160a01b0316856124e2565b888a7fc3f584c404602bca2de1305c366333bc01c086582c86be46e0254affc4e0e63086604051610c9e91815260200190565b60405180910390a36001808601549083015467ffffffffffffffff9091161415610cff57815460ff191660011782554260028301556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b80610d585760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642070726f6f6600000000000000000000000000000000000000604482015260640161052f565b600083815260066020526040812090610d6f612456565b815260208101919091526040016000205460ff1615610dd05760405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c7265616479207375626d6974746564000000000000000000604482015260640161052f565b6000838152600660205260408120600191610de9612456565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f17d5257c85fa8a4b5a4d1f3520e38773826559199467bdce51698fce3d8cae9c838383604051610e4193929190613d44565b60405180910390a1505050565b60408051608081018252600e548152600f546020808301919091526010548284015260115460608301526000848152601290915291909120600d8101544211610ed95760405162461bcd60e51b815260206004820152601960248201527f52657175657374206e6f74207965742074696d6564206f757400000000000000604482015260640161052f565b80546001600160a01b03163314610f325760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b600083815260136020526040812090815460ff166004811115610f5757610f57613008565b14610fa45760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420737461746500000000000000000000000000000000000000604482015260640161052f565b805460ff191660021781558154610fc4906001600160a01b031685612504565b60405184907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a26040805160a0808201835284546001600160a01b03168252825160e081018452600186015467ffffffffffffffff90811682526002870154602083810191909152600388015483870152600488015460608085019190915260058901546080850152600689015494840194909452600788015490911660c08301528301528251908101835260088501805460009461132194938893918501929091908290829061109890613866565b80601f01602080910402602001604051908101604052809291908181526020018280546110c490613866565b80156111115780601f106110e657610100808354040283529160200191611111565b820191906000526020600020905b8154815290600101906020018083116110f457829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061115a90613866565b80601f016020809104026020016040519081016040528092919081815260200182805461118690613866565b80156111d35780601f106111a8576101008083540402835291602001916111d3565b820191906000526020600020905b8154815290600101906020018083116111b657829003601f168201915b505050505081526020016001820180546111ec90613866565b80601f016020809104026020016040519081016040528092919081815260200182805461121890613866565b80156112655780601f1061123a57610100808354040283529160200191611265565b820191906000526020600020905b81548152906001019060200180831161124857829003601f168201915b5050505050815260200160028201805461127e90613866565b80601f01602080910402602001604051908101604052809291908181526020018280546112aa90613866565b80156112f75780601f106112cc576101008083540402835291602001916112f7565b820191906000526020600020905b8154815290600101906020018083116112da57829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e8201548152505061231f565b905080600e60020160008282546113389190613420565b9091555050600e80548291906000906113529084906133ac565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156113bf57600080fd5b505af11580156113d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f79190613d7a565b6114435760405162461bcd60e51b815260206004820152600f60248201527f5769746864726177206661696c65640000000000000000000000000000000000604482015260640161052f565b5050506020810151600f54101561096257610962613d2e565b336000908152600860205260409020606090610a0d90610a0a906124d5565b806000808281526014602052604090205460ff1660048111156114a0576114a0613008565b14156114dd5760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b600082815260146020526040902060048101546001600160a01b031633146115475760405162461bcd60e51b815260206004820152601960248201527f536c6f742066696c6c6564206279206f7468657220686f737400000000000000604482015260640161052f565b600061155284611a2f565b9050600481600481111561156857611568613008565b14156115b65760405162461bcd60e51b815260206004820152600c60248201527f416c726561647920706169640000000000000000000000000000000000000000604482015260640161052f565b60028160048111156115ca576115ca613008565b14156115e3576115de826001015485612526565b61074e565b60038160048111156115f7576115f7613008565b1415611607576115de3385612afd565b600181600481111561161b5761161b613008565b141561074e5761074e846120f0565b60008060006116408461163b612456565b612b1f565b90925090508180156104d3575060025460ff9081169116109392505050565b611667612edf565b816000808281526014602052604090205460ff16600481111561168c5761168c613008565b14156116c95760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b60008381526014602052604090206116df612edf565b600180830154600090815260126020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186529583015467ffffffffffffffff908116875260028401548786015260038401548787015260048401546060808901919091526005850154608089015260068501549288019290925260078401541660c087015292810194909452825191820183526008810180549193850192918290829061178f90613866565b80601f01602080910402602001604051908101604052809291908181526020018280546117bb90613866565b80156118085780601f106117dd57610100808354040283529160200191611808565b820191906000526020600020905b8154815290600101906020018083116117eb57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061185190613866565b80601f016020809104026020016040519081016040528092919081815260200182805461187d90613866565b80156118ca5780601f1061189f576101008083540402835291602001916118ca565b820191906000526020600020905b8154815290600101906020018083116118ad57829003601f168201915b505050505081526020016001820180546118e390613866565b80601f016020809104026020016040519081016040528092919081815260200182805461190f90613866565b801561195c5780601f106119315761010080835404028352916020019161195c565b820191906000526020600020905b81548152906001019060200180831161193f57829003601f168201915b5050505050815260200160028201805461197590613866565b80601f01602080910402602001604051908101604052809291908181526020018280546119a190613866565b80156119ee5780601f106119c3576101008083540402835291602001916119ee565b820191906000526020600020905b8154815290600101906020018083116119d157829003601f168201915b505050919092525050509052508152600d820154602080830191909152600e9092015460409091015290825260029092015491810191909152915050919050565b60008181526014602052604081206001810154611a4f5750600092915050565b6000611a5e82600101546104db565b90506004825460ff166004811115611a7857611a78613008565b1415611a88575060049392505050565b6002816004811115611a9c57611a9c613008565b1415611aac575060029392505050565b6003816004811115611ac057611ac0613008565b1415611ad0575060029392505050565b6004816004811115611ae457611ae4613008565b1415611af4575060039392505050565b505460ff1692915050565b60006109d282611b0d612456565b612c02565b611b1a612eff565b60008281526012602052604090205482906001600160a01b0316611b725760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b600083815260126020908152604091829020825160a0808201855282546001600160a01b03168252845160e081018652600184015467ffffffffffffffff908116825260028501548287015260038501548288015260048501546060808401919091526005860154608084015260068601549383019390935260078501541660c0820152938201939093528351928301845260088201805491949293928501929182908290611c2090613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4c90613866565b8015611c995780601f10611c6e57610100808354040283529160200191611c99565b820191906000526020600020905b815481529060010190602001808311611c7c57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff16825283015280516060810182526002840180549290930192909182908290611ce290613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611d0e90613866565b8015611d5b5780601f10611d3057610100808354040283529160200191611d5b565b820191906000526020600020905b815481529060010190602001808311611d3e57829003601f168201915b50505050508152602001600182018054611d7490613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611da090613866565b8015611ded5780601f10611dc257610100808354040283529160200191611ded565b820191906000526020600020905b815481529060010190602001808311611dd057829003601f168201915b50505050508152602001600282018054611e0690613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3290613866565b8015611e7f5780601f10611e5457610100808354040283529160200191611e7f565b820191906000526020600020905b815481529060010190602001808311611e6257829003601f168201915b505050919092525050509052508152600d8201546020820152600e909101546040909101529392505050565b6000818310611eba5781611ebc565b825b9392505050565b6000611ece82612c35565b9050428110611f1f5760405162461bcd60e51b815260206004820152601860248201527f506572696f6420686173206e6f7420656e646564207965740000000000000000604482015260640161052f565b600154611f2c9082613420565b4210611f7a5760405162461bcd60e51b815260206004820152601460248201527f56616c69646174696f6e2074696d6564206f7574000000000000000000000000604482015260640161052f565b600083815260066020908152604080832085845290915290205460ff1615611fe45760405162461bcd60e51b815260206004820181905260248201527f50726f6f6620776173207375626d69747465642c206e6f74206d697373696e67604482015260640161052f565b611fee8383612c02565b61203a5760405162461bcd60e51b815260206004820152601660248201527f50726f6f6620776173206e6f7420726571756972656400000000000000000000604482015260640161052f565b600083815260076020908152604080832085845290915290205460ff16156120a45760405162461bcd60e51b815260206004820152601f60248201527f50726f6f6620616c7265616479206d61726b6564206173206d697373696e6700604482015260640161052f565b60008381526007602090815260408083208584528252808320805460ff19166001908117909155868452600590925282208054919290916120e6908490613420565b9091555050505050565b60408051608081018252600e548152600f54602080830191909152601054828401526011546060830152600084815260148252838120600181015480835260139093529390206004840154929392612151906001600160a01b031686612afd565b6000858152601460205260408120805460ff19168155600180820183905560028201839055600382018390556004909101805473ffffffffffffffffffffffffffffffffffffffff191690558281018054919290916121b19084906133ac565b909155505060405185815282907f941c699bbe1379ca62b68c0380eae97577c06a8804616064ffc3eebd40a0510a9060200160405180910390a2600085815260056020526040812055600082815260126020526040812060018084015490820154919291612229919067ffffffffffffffff166133ac565b600783015490915067ffffffffffffffff168111801561225e57506001835460ff16600481111561225c5761225c613008565b145b156122aa57825460ff191660041783556122796001426133ac565b600384015560405184907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a25b50505050508060200151600e60010154101561096257610962613d2e565b6000816040516020016122db9190613383565b604051602081830303815290604052805190602001209050919050565b6001600160a01b038216600090815260086020526040902061231a9082612c48565b505050565b600061232a82612c54565b6020830151516109d2919067ffffffffffffffff166133ed565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd90606401602060405180830381600087803b1580156123d257600080fd5b505af11580156123e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240a9190613d7a565b61231a5760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015260640161052f565b6000610a0d42612c70565b6000611ebc6124708484612475565b612c9c565b600080612484610100436133d9565b90506000612494610100856133d9565b905060006124a4610100876133d9565b90506000610100826124b68587613420565b6124c09190613420565b6124ca91906133d9565b979650505050505050565b60606000611ebc83612cf2565b6001600160a01b038216600090815260096020526040902061231a9082612c48565b6001600160a01b038216600090815260086020526040902061231a9082612d4e565b60008281526012602052604090205482906001600160a01b031661257e5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b60408051608081018252600e548152600f54602080830191909152601054828401526011546060830152600086815260138252838120601290925292909220825460ff1916600317835580549192916125e0906001600160a01b031687612504565b60008581526014602052604090206004810154612606906001600160a01b031687612afd565b6003808201546000898152601260209081526040808320815160a0808201845282546001600160a01b03168252835160e081018552600184015467ffffffffffffffff90811682526002850154828801529884015481860152600484015460608083019190915260058501546080830152600685015492820192909252600784015490981660c08901529381019690965281519283018252600881018054949661294995909492938501929190829082906126c090613866565b80601f01602080910402602001604051908101604052809291908181526020018280546126ec90613866565b80156127395780601f1061270e57610100808354040283529160200191612739565b820191906000526020600020905b81548152906001019060200180831161271c57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061278290613866565b80601f01602080910402602001604051908101604052809291908181526020018280546127ae90613866565b80156127fb5780601f106127d0576101008083540402835291602001916127fb565b820191906000526020600020905b8154815290600101906020018083116127de57829003601f168201915b5050505050815260200160018201805461281490613866565b80601f016020809104026020016040519081016040528092919081815260200182805461284090613866565b801561288d5780601f106128625761010080835404028352916020019161288d565b820191906000526020600020905b81548152906001019060200180831161287057829003601f168201915b505050505081526020016002820180546128a690613866565b80601f01602080910402602001604051908101604052809291908181526020018280546128d290613866565b801561291f5780601f106128f45761010080835404028352916020019161291f565b820191906000526020600020905b81548152906001019060200180831161290257829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e82015481525050612c54565b6129539190613420565b905080600e600201600082825461296a9190613420565b9091555050600e80548291906000906129849084906133ac565b9091555050815460ff1916600490811783558083015460405163a9059cbb60e01b81526001600160a01b0391821692810192909252602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b158015612a0657600080fd5b505af1158015612a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3e9190613d7a565b612a8a5760405162461bcd60e51b815260206004820152600e60248201527f5061796d656e74206661696c6564000000000000000000000000000000000000604482015260640161052f565b505050506020810151600f541015612aa457612aa4613d2e565b60408101516010541015612aba57612aba613d2e565b60608101516011541015612ad057612ad0613d2e565b601154601054600e54612ae39190613420565b612aed9190613420565b600f541461074e5761074e613d2e565b6001600160a01b038216600090815260096020526040902061231a9082612d4e565b6000806000612b2d85611a2f565b60008681526003602052604081205491925090612b4990612c70565b90506001826004811115612b5f57612b5f613008565b141580612b735750612b718582612d5a565b155b15612b8657600080935093505050612bfb565b612b908686612475565b92506000612b9d84612c9c565b60025490915060009061010090612bb79060ff1682613d9c565b60008a815260046020526040902054612bd49161ffff16906133ed565b612bde919061340c565b9050801580612bf45750612bf281836133d9565b155b9550505050505b9250929050565b6000806000612c118585612b1f565b9092509050818015612c2c575060025460ff90811690821610155b95945050505050565b60006109d2612c4383612d64565b612d71565b6000611ebc8383612d9d565b602081015160808101516040909101516000916109d2916133ed565b60006109d27f00000000000000000000000000000000000000000000000000000000000000008361340c565b60008060ff8316612cae6001436133ac565b612cb891906133ac565b40905080612cc857612cc8613d2e565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b606081600001805480602002602001604051908101604052809291908181526020018280548015612d4257602002820191906000526020600020905b815481526020019060010190808311612d2e575b50505050509050919050565b6000611ebc8383612dec565b6000818311611ebc565b60006109d2826001613420565b60006109d27f0000000000000000000000000000000000000000000000000000000000000000836133ed565b6000818152600183016020526040812054612de4575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109d2565b5060006109d2565b60008181526001830160205260408120548015612ed5576000612e106001836133ac565b8554909150600090612e24906001906133ac565b9050818114612e89576000866000018281548110612e4457612e44613dbf565b9060005260206000200154905080876000018481548110612e6757612e67613dbf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e9a57612e9a613dd5565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109d2565b60009150506109d2565b6040518060400160405280612ef2612eff565b8152602001600081525090565b6040518060a0016040528060006001600160a01b03168152602001612f6e6040518060e00160405280600067ffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600067ffffffffffffffff1681525090565b8152602001612f7b612f8f565b815260006020820181905260409091015290565b604051806060016040528060608152602001612fc16040518060200160405280600067ffffffffffffffff1681525090565b8152602001612fea60405180606001604052806060815260200160608152602001606081525090565b905290565b60006020828403121561300157600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061303c57634e487b7160e01b600052602160045260246000fd5b50565b6020810161304c8361301e565b91905290565b6000806040838503121561306557600080fd5b50508035926020909101359150565b60006020828403121561308657600080fd5b813567ffffffffffffffff81111561309d57600080fd5b82016101608185031215611ebc57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156130e8578351835292840192918401916001016130cc565b50909695505050505050565b60008083601f84011261310657600080fd5b50813567ffffffffffffffff81111561311e57600080fd5b602083019150836020828501011115612bfb57600080fd5b6000806000806060858703121561314c57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561317157600080fd5b61317d878288016130f4565b95989497509550505050565b60008060006040848603121561319e57600080fd5b83359250602084013567ffffffffffffffff8111156131bc57600080fd5b6131c8868287016130f4565b9497909650939450505050565b6000815180845260005b818110156131fb576020818501810151868301820152016131df565b8181111561320d576000602083870101525b50601f01601f19169290920160200192915050565b600081516060845261323760608501826131d5565b905067ffffffffffffffff6020840151511660208501526040830151848203604086015280516060835261326e60608401826131d5565b90506020820151838203602085015261328782826131d5565b9150506040820151915082810360408401526132a381836131d5565b9695505050505050565b60006101606001600160a01b038351168452602083015167ffffffffffffffff808251166020870152602082015160408701526040820151606087015260608201516080870152608082015160a087015260a082015160c08701528060c08301511660e0870152505060408301518161010086015261332e82860182613222565b915050606083015161012085015260808301516101408501528091505092915050565b60208152600082516040602084015261336d60608401826132ad565b9050602084015160408401528091505092915050565b602081526000611ebc60208301846132ad565b634e487b7160e01b600052601160045260246000fd5b6000828210156133be576133be613396565b500390565b634e487b7160e01b600052601260045260246000fd5b6000826133e8576133e86133c3565b500690565b600081600019048311821515161561340757613407613396565b500290565b60008261341b5761341b6133c3565b500490565b6000821982111561343357613433613396565b500190565b6001600160a01b038116811461303c57600080fd5b60006020828403121561345f57600080fd5b8135611ebc81613438565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156134a3576134a361346a565b60405290565b6040516020810167ffffffffffffffff811182821017156134a3576134a361346a565b60405160a0810167ffffffffffffffff811182821017156134a3576134a361346a565b60405160e0810167ffffffffffffffff811182821017156134a3576134a361346a565b67ffffffffffffffff8116811461303c57600080fd5b600067ffffffffffffffff808411156135435761354361346a565b604051601f8501601f19908116603f0116810190828211818310171561356b5761356b61346a565b8160405280935085815286868601111561358457600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126135af57600080fd5b611ebc83833560208501613528565b6000606082840312156135d057600080fd5b6135d8613480565b9050813567ffffffffffffffff808211156135f257600080fd5b6135fe8583860161359e565b8352602084013591508082111561361457600080fd5b6136208583860161359e565b6020840152604084013591508082111561363957600080fd5b506136468482850161359e565b60408301525092915050565b6000818303606081121561366557600080fd5b61366d613480565b9150823567ffffffffffffffff8082111561368757600080fd5b818501915085601f83011261369b57600080fd5b6136aa86833560208501613528565b84526020601f19840112156136be57600080fd5b6136c66134a9565b9250602085013591506136d882613512565b81835282602085015260408501359250808311156136f557600080fd5b5050613646848285016135be565b600081360361016081121561371757600080fd5b61371f6134cc565b833561372a81613438565b815260e0601f198301121561373e57600080fd5b6137466134ef565b9150602084013561375681613512565b8083525060408401356020830152606084013560408301526080840135606083015260a0840135608083015260c084013560a083015260e084013561379a81613512565b60c083015260208101919091526101008301359067ffffffffffffffff8211156137c357600080fd5b6137cf36838601613652565b604082015261012084013560608201526101409093013560808401525090919050565b600081356109d281613512565b60008235605e1983360301811261381557600080fd5b9190910192915050565b6000808335601e1984360301811261383657600080fd5b83018035915067ffffffffffffffff82111561385157600080fd5b602001915036819003821315612bfb57600080fd5b600181811c9082168061387a57607f821691505b602082108114156105c757634e487b7160e01b600052602260045260246000fd5b601f82111561231a57600081815260208120601f850160051c810160208610156138c25750805b601f850160051c820191505b818110156138e1578281556001016138ce565b505050505050565b81356138f481613512565b815467ffffffffffffffff191667ffffffffffffffff8216178255505050565b67ffffffffffffffff83111561392c5761392c61346a565b6139408361393a8354613866565b8361389b565b6000601f841160018114613974576000851561395c5750838201355b600019600387901b1c1916600186901b17835561074c565b600083815260209020601f19861690835b828110156139a55786850135825560209485019460019092019101613985565b50868210156139c25760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6139de828361381f565b67ffffffffffffffff8111156139f6576139f661346a565b613a0a81613a048554613866565b8561389b565b6000601f821160018114613a3e5760008315613a265750838201355b600019600385901b1c1916600184901b178555613a98565b600085815260209020601f19841690835b82811015613a6f5786850135825560209485019460019092019101613a4f565b5084821015613a8c5760001960f88660031b161c19848701351681555b505060018360011b0185555b50505050613aa9602083018361381f565b613ab7818360018601613914565b5050613ac6604083018361381f565b61074e818360028601613914565b613ade828361381f565b67ffffffffffffffff811115613af657613af661346a565b613b0481613a048554613866565b6000601f821160018114613b385760008315613b205750838201355b600019600385901b1c1916600184901b178555613b92565b600085815260209020601f19841690835b82811015613b695786850135825560209485019460019092019101613b49565b5084821015613b865760001960f88660031b161c19848701351681555b505060018360011b0185555b50505050613ba660208301600183016138e9565b6109bb613bb660408401846137ff565b600283016139d4565b8135613bca81613438565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff19835416178255506020820135613bff81613512565b60018201805467ffffffffffffffff191667ffffffffffffffff83161790555060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155613c83613c6060e084016137f2565b6007830167ffffffffffffffff821667ffffffffffffffff198254161781555050565b613c9d613c946101008401846137ff565b60088301613ad4565b610120820135600d820155610140820135600e8201555050565b82815261010081018235613cca81613512565b67ffffffffffffffff8082166020850152602085013560408501526040850135606085015260608501356080850152608085013560a085015260a085013560c085015260c08501359150613d1d82613512565b80821660e085015250509392505050565b634e487b7160e01b600052600160045260246000fd5b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215613d8c57600080fd5b81518015158114611ebc57600080fd5b600061ffff83811690831681811015613db757613db7613396565b039392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220f8596c0debde8f4c5f106b1a1a26548b502491cf402f7c606b84ced06c2d466f64736f6c63430008080033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101775760003560e01c80636e2b54ee116100d8578063b396dc791161008c578063f752196b11610066578063f752196b146103fd578063fb1e61ca1461041d578063fc0c546a1461043d57600080fd5b8063b396dc79146103b7578063be5cdc48146103d7578063c0cc4add146103ea57600080fd5b80639777b72c116100bd5780639777b72c14610379578063a29c29a414610381578063a3a0807e1461039457600080fd5b80636e2b54ee146102a157806379502c55146102b457600080fd5b80634641dce61161012f5780636368a471116101145780636368a47114610237578063645116d81461024a5780636b00c8cf1461025d57600080fd5b80634641dce6146101fd5780635da738351461022257600080fd5b806308695fcd1161016057806308695fcd146101c25780630eb6c86f146101d7578063458d2bf1146101ea57600080fd5b806302fa8e651461017c57806305b90773146101a2575b600080fd5b61018f61018a366004612fef565b610464565b6040519081526020015b60405180910390f35b6101b56101b0366004612fef565b6104db565b604051610199919061303f565b6101d56101d0366004613052565b6105cd565b005b6101d56101e5366004613074565b610754565b61018f6101f8366004612fef565b6109bf565b61021061020b366004612fef565b6109d8565b60405160ff9091168152602001610199565b61022a6109eb565b60405161019991906130b0565b6101d5610245366004613136565b610a12565b6101d5610258366004613189565b610d0b565b61028961026b366004612fef565b6000908152601460205260409020600401546001600160a01b031690565b6040516001600160a01b039091168152602001610199565b6101d56102af366004612fef565b610e4e565b60408051608081018252600a5460ff80821683526101008204811660208085019190915261ffff6201000084041684860152640100000000909204811660608085019190915284519081018552600b548152600c5492810192909252600d5416928101929092526103229182565b60408051835160ff90811682526020808601518216818401528584015161ffff1683850152606095860151821695830195909552835160808301529383015160a082015291015190911660c082015260e001610199565b61022a61145c565b6101d561038f366004612fef565b61147b565b6103a76103a2366004612fef565b61162a565b6040519015158152602001610199565b6103ca6103c5366004612fef565b61165f565b6040516101999190613351565b6101b56103e5366004612fef565b611a2f565b6103a76103f8366004612fef565b611aff565b61018f61040b366004612fef565b60009081526005602052604090205490565b61043061042b366004612fef565b611b12565b6040516101999190613383565b6102897f000000000000000000000000000000000000000000000000000000000000000081565b60008181526013602052604081206003015481610480846104db565b9050600081600481111561049657610496613008565b14806104b3575060018160048111156104b1576104b1613008565b145b156104bf575092915050565b6104d3826104ce6001426133ac565b611eab565b949350505050565b60008181526012602052604081205482906001600160a01b03166105385760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b60448201526064015b60405180910390fd5b600083815260136020526040812090815460ff16600481111561055d5761055d613008565b14801561057a57506000848152601260205260409020600d015442115b156105895760029250506105c7565b6001815460ff1660048111156105a1576105a1613008565b1480156105b15750806003015442115b156105c05760039250506105c7565b5460ff1691505b50919050565b60016105d883611a2f565b60048111156105e9576105e9613008565b146106365760405162461bcd60e51b815260206004820152601960248201527f536c6f74206e6f7420616363657074696e672070726f6f667300000000000000604482015260640161052f565b6106408282611ec3565b6000828152601460209081526040808320600181015484526012909252909120600a5461ffff62010000909104166106848560009081526005602052604090205490565b61068e91906133d9565b61074e57600a5460068201546000916064916106b591640100000000900460ff16906133ed565b6106bf919061340c565b9050808360030160008282546106d591906133ac565b9091555050601180548291906000906106ef908490613420565b9091555050600e80548291906000906107099084906133ac565b9091555050600a54600086815260056020526040902054610100820460ff169162010000900461ffff169061073e919061340c565b1061074c5761074c856120f0565b505b50505050565b60408051608081018252600e548152600f546020808301919091526010549282019290925260115460608201529033906107909084018461344d565b6001600160a01b0316146107e65760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b60006107f96107f484613703565b6122c8565b6000818152601260205260409020549091506001600160a01b0316156108615760405162461bcd60e51b815260206004820152601660248201527f5265717565737420616c72656164792065786973747300000000000000000000604482015260640161052f565b6000818152601260205260409020839061087b8282613bbf565b5061088c9050606084013542613420565b6000828152601360209081526040909120600301919091556108ba906108b49085018561344d565b826122f8565b60006108cd6108c885613703565b61231f565b905080600e60010160008282546108e49190613420565b9091555050600e80548291906000906108fe908490613420565b9091555061090e90503382612344565b7ff6285655f5f3c277c1bfd91fe7bf7c48929cce5114cf4e3892ebaf7f7af53de98285602001604051610942929190613cb7565b60405180910390a150506020810151600f54101561096257610962613d2e565b6040810151601054101561097857610978613d2e565b6060810151601154101561098e5761098e613d2e565b601154601054600e546109a19190613420565b6109ab9190613420565b600f54146109bb576109bb613d2e565b5050565b60006109d2826109cd612456565b612461565b92915050565b60006109d2826109e6612456565b612475565b336000908152600960205260409020606090610a0d90610a0a906124d5565b90565b905090565b60008481526012602052604090205484906001600160a01b0316610a6a5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000858152601260205260409020600181015467ffffffffffffffff168510610ad55760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420736c6f740000000000000000000000000000000000000000604482015260640161052f565b604080516020808201899052818301889052825180830384018152606090920190925280519101206000906000818152601460205260408120600181018a905560028101899055919250610b2883611a2f565b6004811115610b3957610b39613008565b14610b865760405162461bcd60e51b815260206004820152601060248201527f536c6f74206973206e6f74206672656500000000000000000000000000000000604482015260640161052f565b60048084015460008481526003602090815260408083204290559390529190912055610bb3828787610d0b565b60048101805473ffffffffffffffffffffffffffffffffffffffff191633179055805460ff191660019081178255600089815260136020526040812080830180549193929091610c04908490613420565b90915550506006840154610c183382612344565b80600e6001016000828254610c2d9190613420565b9091555050600e8054829190600090610c47908490613420565b9091555050600383018190556004830154610c6b906001600160a01b0316856124e2565b888a7fc3f584c404602bca2de1305c366333bc01c086582c86be46e0254affc4e0e63086604051610c9e91815260200190565b60405180910390a36001808601549083015467ffffffffffffffff9091161415610cff57815460ff191660011782554260028301556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b80610d585760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642070726f6f6600000000000000000000000000000000000000604482015260640161052f565b600083815260066020526040812090610d6f612456565b815260208101919091526040016000205460ff1615610dd05760405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c7265616479207375626d6974746564000000000000000000604482015260640161052f565b6000838152600660205260408120600191610de9612456565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f17d5257c85fa8a4b5a4d1f3520e38773826559199467bdce51698fce3d8cae9c838383604051610e4193929190613d44565b60405180910390a1505050565b60408051608081018252600e548152600f546020808301919091526010548284015260115460608301526000848152601290915291909120600d8101544211610ed95760405162461bcd60e51b815260206004820152601960248201527f52657175657374206e6f74207965742074696d6564206f757400000000000000604482015260640161052f565b80546001600160a01b03163314610f325760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b600083815260136020526040812090815460ff166004811115610f5757610f57613008565b14610fa45760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420737461746500000000000000000000000000000000000000604482015260640161052f565b805460ff191660021781558154610fc4906001600160a01b031685612504565b60405184907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a26040805160a0808201835284546001600160a01b03168252825160e081018452600186015467ffffffffffffffff90811682526002870154602083810191909152600388015483870152600488015460608085019190915260058901546080850152600689015494840194909452600788015490911660c08301528301528251908101835260088501805460009461132194938893918501929091908290829061109890613866565b80601f01602080910402602001604051908101604052809291908181526020018280546110c490613866565b80156111115780601f106110e657610100808354040283529160200191611111565b820191906000526020600020905b8154815290600101906020018083116110f457829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061115a90613866565b80601f016020809104026020016040519081016040528092919081815260200182805461118690613866565b80156111d35780601f106111a8576101008083540402835291602001916111d3565b820191906000526020600020905b8154815290600101906020018083116111b657829003601f168201915b505050505081526020016001820180546111ec90613866565b80601f016020809104026020016040519081016040528092919081815260200182805461121890613866565b80156112655780601f1061123a57610100808354040283529160200191611265565b820191906000526020600020905b81548152906001019060200180831161124857829003601f168201915b5050505050815260200160028201805461127e90613866565b80601f01602080910402602001604051908101604052809291908181526020018280546112aa90613866565b80156112f75780601f106112cc576101008083540402835291602001916112f7565b820191906000526020600020905b8154815290600101906020018083116112da57829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e8201548152505061231f565b905080600e60020160008282546113389190613420565b9091555050600e80548291906000906113529084906133ac565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156113bf57600080fd5b505af11580156113d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f79190613d7a565b6114435760405162461bcd60e51b815260206004820152600f60248201527f5769746864726177206661696c65640000000000000000000000000000000000604482015260640161052f565b5050506020810151600f54101561096257610962613d2e565b336000908152600860205260409020606090610a0d90610a0a906124d5565b806000808281526014602052604090205460ff1660048111156114a0576114a0613008565b14156114dd5760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b600082815260146020526040902060048101546001600160a01b031633146115475760405162461bcd60e51b815260206004820152601960248201527f536c6f742066696c6c6564206279206f7468657220686f737400000000000000604482015260640161052f565b600061155284611a2f565b9050600481600481111561156857611568613008565b14156115b65760405162461bcd60e51b815260206004820152600c60248201527f416c726561647920706169640000000000000000000000000000000000000000604482015260640161052f565b60028160048111156115ca576115ca613008565b14156115e3576115de826001015485612526565b61074e565b60038160048111156115f7576115f7613008565b1415611607576115de3385612afd565b600181600481111561161b5761161b613008565b141561074e5761074e846120f0565b60008060006116408461163b612456565b612b1f565b90925090508180156104d3575060025460ff9081169116109392505050565b611667612edf565b816000808281526014602052604090205460ff16600481111561168c5761168c613008565b14156116c95760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b60008381526014602052604090206116df612edf565b600180830154600090815260126020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186529583015467ffffffffffffffff908116875260028401548786015260038401548787015260048401546060808901919091526005850154608089015260068501549288019290925260078401541660c087015292810194909452825191820183526008810180549193850192918290829061178f90613866565b80601f01602080910402602001604051908101604052809291908181526020018280546117bb90613866565b80156118085780601f106117dd57610100808354040283529160200191611808565b820191906000526020600020905b8154815290600101906020018083116117eb57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061185190613866565b80601f016020809104026020016040519081016040528092919081815260200182805461187d90613866565b80156118ca5780601f1061189f576101008083540402835291602001916118ca565b820191906000526020600020905b8154815290600101906020018083116118ad57829003601f168201915b505050505081526020016001820180546118e390613866565b80601f016020809104026020016040519081016040528092919081815260200182805461190f90613866565b801561195c5780601f106119315761010080835404028352916020019161195c565b820191906000526020600020905b81548152906001019060200180831161193f57829003601f168201915b5050505050815260200160028201805461197590613866565b80601f01602080910402602001604051908101604052809291908181526020018280546119a190613866565b80156119ee5780601f106119c3576101008083540402835291602001916119ee565b820191906000526020600020905b8154815290600101906020018083116119d157829003601f168201915b505050919092525050509052508152600d820154602080830191909152600e9092015460409091015290825260029092015491810191909152915050919050565b60008181526014602052604081206001810154611a4f5750600092915050565b6000611a5e82600101546104db565b90506004825460ff166004811115611a7857611a78613008565b1415611a88575060049392505050565b6002816004811115611a9c57611a9c613008565b1415611aac575060029392505050565b6003816004811115611ac057611ac0613008565b1415611ad0575060029392505050565b6004816004811115611ae457611ae4613008565b1415611af4575060039392505050565b505460ff1692915050565b60006109d282611b0d612456565b612c02565b611b1a612eff565b60008281526012602052604090205482906001600160a01b0316611b725760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b600083815260126020908152604091829020825160a0808201855282546001600160a01b03168252845160e081018652600184015467ffffffffffffffff908116825260028501548287015260038501548288015260048501546060808401919091526005860154608084015260068601549383019390935260078501541660c0820152938201939093528351928301845260088201805491949293928501929182908290611c2090613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4c90613866565b8015611c995780601f10611c6e57610100808354040283529160200191611c99565b820191906000526020600020905b815481529060010190602001808311611c7c57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff16825283015280516060810182526002840180549290930192909182908290611ce290613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611d0e90613866565b8015611d5b5780601f10611d3057610100808354040283529160200191611d5b565b820191906000526020600020905b815481529060010190602001808311611d3e57829003601f168201915b50505050508152602001600182018054611d7490613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611da090613866565b8015611ded5780601f10611dc257610100808354040283529160200191611ded565b820191906000526020600020905b815481529060010190602001808311611dd057829003601f168201915b50505050508152602001600282018054611e0690613866565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3290613866565b8015611e7f5780601f10611e5457610100808354040283529160200191611e7f565b820191906000526020600020905b815481529060010190602001808311611e6257829003601f168201915b505050919092525050509052508152600d8201546020820152600e909101546040909101529392505050565b6000818310611eba5781611ebc565b825b9392505050565b6000611ece82612c35565b9050428110611f1f5760405162461bcd60e51b815260206004820152601860248201527f506572696f6420686173206e6f7420656e646564207965740000000000000000604482015260640161052f565b600154611f2c9082613420565b4210611f7a5760405162461bcd60e51b815260206004820152601460248201527f56616c69646174696f6e2074696d6564206f7574000000000000000000000000604482015260640161052f565b600083815260066020908152604080832085845290915290205460ff1615611fe45760405162461bcd60e51b815260206004820181905260248201527f50726f6f6620776173207375626d69747465642c206e6f74206d697373696e67604482015260640161052f565b611fee8383612c02565b61203a5760405162461bcd60e51b815260206004820152601660248201527f50726f6f6620776173206e6f7420726571756972656400000000000000000000604482015260640161052f565b600083815260076020908152604080832085845290915290205460ff16156120a45760405162461bcd60e51b815260206004820152601f60248201527f50726f6f6620616c7265616479206d61726b6564206173206d697373696e6700604482015260640161052f565b60008381526007602090815260408083208584528252808320805460ff19166001908117909155868452600590925282208054919290916120e6908490613420565b9091555050505050565b60408051608081018252600e548152600f54602080830191909152601054828401526011546060830152600084815260148252838120600181015480835260139093529390206004840154929392612151906001600160a01b031686612afd565b6000858152601460205260408120805460ff19168155600180820183905560028201839055600382018390556004909101805473ffffffffffffffffffffffffffffffffffffffff191690558281018054919290916121b19084906133ac565b909155505060405185815282907f941c699bbe1379ca62b68c0380eae97577c06a8804616064ffc3eebd40a0510a9060200160405180910390a2600085815260056020526040812055600082815260126020526040812060018084015490820154919291612229919067ffffffffffffffff166133ac565b600783015490915067ffffffffffffffff168111801561225e57506001835460ff16600481111561225c5761225c613008565b145b156122aa57825460ff191660041783556122796001426133ac565b600384015560405184907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a25b50505050508060200151600e60010154101561096257610962613d2e565b6000816040516020016122db9190613383565b604051602081830303815290604052805190602001209050919050565b6001600160a01b038216600090815260086020526040902061231a9082612c48565b505050565b600061232a82612c54565b6020830151516109d2919067ffffffffffffffff166133ed565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd90606401602060405180830381600087803b1580156123d257600080fd5b505af11580156123e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240a9190613d7a565b61231a5760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015260640161052f565b6000610a0d42612c70565b6000611ebc6124708484612475565b612c9c565b600080612484610100436133d9565b90506000612494610100856133d9565b905060006124a4610100876133d9565b90506000610100826124b68587613420565b6124c09190613420565b6124ca91906133d9565b979650505050505050565b60606000611ebc83612cf2565b6001600160a01b038216600090815260096020526040902061231a9082612c48565b6001600160a01b038216600090815260086020526040902061231a9082612d4e565b60008281526012602052604090205482906001600160a01b031661257e5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b60408051608081018252600e548152600f54602080830191909152601054828401526011546060830152600086815260138252838120601290925292909220825460ff1916600317835580549192916125e0906001600160a01b031687612504565b60008581526014602052604090206004810154612606906001600160a01b031687612afd565b6003808201546000898152601260209081526040808320815160a0808201845282546001600160a01b03168252835160e081018552600184015467ffffffffffffffff90811682526002850154828801529884015481860152600484015460608083019190915260058501546080830152600685015492820192909252600784015490981660c08901529381019690965281519283018252600881018054949661294995909492938501929190829082906126c090613866565b80601f01602080910402602001604051908101604052809291908181526020018280546126ec90613866565b80156127395780601f1061270e57610100808354040283529160200191612739565b820191906000526020600020905b81548152906001019060200180831161271c57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061278290613866565b80601f01602080910402602001604051908101604052809291908181526020018280546127ae90613866565b80156127fb5780601f106127d0576101008083540402835291602001916127fb565b820191906000526020600020905b8154815290600101906020018083116127de57829003601f168201915b5050505050815260200160018201805461281490613866565b80601f016020809104026020016040519081016040528092919081815260200182805461284090613866565b801561288d5780601f106128625761010080835404028352916020019161288d565b820191906000526020600020905b81548152906001019060200180831161287057829003601f168201915b505050505081526020016002820180546128a690613866565b80601f01602080910402602001604051908101604052809291908181526020018280546128d290613866565b801561291f5780601f106128f45761010080835404028352916020019161291f565b820191906000526020600020905b81548152906001019060200180831161290257829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e82015481525050612c54565b6129539190613420565b905080600e600201600082825461296a9190613420565b9091555050600e80548291906000906129849084906133ac565b9091555050815460ff1916600490811783558083015460405163a9059cbb60e01b81526001600160a01b0391821692810192909252602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b158015612a0657600080fd5b505af1158015612a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3e9190613d7a565b612a8a5760405162461bcd60e51b815260206004820152600e60248201527f5061796d656e74206661696c6564000000000000000000000000000000000000604482015260640161052f565b505050506020810151600f541015612aa457612aa4613d2e565b60408101516010541015612aba57612aba613d2e565b60608101516011541015612ad057612ad0613d2e565b601154601054600e54612ae39190613420565b612aed9190613420565b600f541461074e5761074e613d2e565b6001600160a01b038216600090815260096020526040902061231a9082612d4e565b6000806000612b2d85611a2f565b60008681526003602052604081205491925090612b4990612c70565b90506001826004811115612b5f57612b5f613008565b141580612b735750612b718582612d5a565b155b15612b8657600080935093505050612bfb565b612b908686612475565b92506000612b9d84612c9c565b60025490915060009061010090612bb79060ff1682613d9c565b60008a815260046020526040902054612bd49161ffff16906133ed565b612bde919061340c565b9050801580612bf45750612bf281836133d9565b155b9550505050505b9250929050565b6000806000612c118585612b1f565b9092509050818015612c2c575060025460ff90811690821610155b95945050505050565b60006109d2612c4383612d64565b612d71565b6000611ebc8383612d9d565b602081015160808101516040909101516000916109d2916133ed565b60006109d27f00000000000000000000000000000000000000000000000000000000000000008361340c565b60008060ff8316612cae6001436133ac565b612cb891906133ac565b40905080612cc857612cc8613d2e565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b606081600001805480602002602001604051908101604052809291908181526020018280548015612d4257602002820191906000526020600020905b815481526020019060010190808311612d2e575b50505050509050919050565b6000611ebc8383612dec565b6000818311611ebc565b60006109d2826001613420565b60006109d27f0000000000000000000000000000000000000000000000000000000000000000836133ed565b6000818152600183016020526040812054612de4575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109d2565b5060006109d2565b60008181526001830160205260408120548015612ed5576000612e106001836133ac565b8554909150600090612e24906001906133ac565b9050818114612e89576000866000018281548110612e4457612e44613dbf565b9060005260206000200154905080876000018481548110612e6757612e67613dbf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e9a57612e9a613dd5565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109d2565b60009150506109d2565b6040518060400160405280612ef2612eff565b8152602001600081525090565b6040518060a0016040528060006001600160a01b03168152602001612f6e6040518060e00160405280600067ffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600067ffffffffffffffff1681525090565b8152602001612f7b612f8f565b815260006020820181905260409091015290565b604051806060016040528060608152602001612fc16040518060200160405280600067ffffffffffffffff1681525090565b8152602001612fea60405180606001604052806060815260200160608152602001606081525090565b905290565b60006020828403121561300157600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6005811061303c57634e487b7160e01b600052602160045260246000fd5b50565b6020810161304c8361301e565b91905290565b6000806040838503121561306557600080fd5b50508035926020909101359150565b60006020828403121561308657600080fd5b813567ffffffffffffffff81111561309d57600080fd5b82016101608185031215611ebc57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156130e8578351835292840192918401916001016130cc565b50909695505050505050565b60008083601f84011261310657600080fd5b50813567ffffffffffffffff81111561311e57600080fd5b602083019150836020828501011115612bfb57600080fd5b6000806000806060858703121561314c57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561317157600080fd5b61317d878288016130f4565b95989497509550505050565b60008060006040848603121561319e57600080fd5b83359250602084013567ffffffffffffffff8111156131bc57600080fd5b6131c8868287016130f4565b9497909650939450505050565b6000815180845260005b818110156131fb576020818501810151868301820152016131df565b8181111561320d576000602083870101525b50601f01601f19169290920160200192915050565b600081516060845261323760608501826131d5565b905067ffffffffffffffff6020840151511660208501526040830151848203604086015280516060835261326e60608401826131d5565b90506020820151838203602085015261328782826131d5565b9150506040820151915082810360408401526132a381836131d5565b9695505050505050565b60006101606001600160a01b038351168452602083015167ffffffffffffffff808251166020870152602082015160408701526040820151606087015260608201516080870152608082015160a087015260a082015160c08701528060c08301511660e0870152505060408301518161010086015261332e82860182613222565b915050606083015161012085015260808301516101408501528091505092915050565b60208152600082516040602084015261336d60608401826132ad565b9050602084015160408401528091505092915050565b602081526000611ebc60208301846132ad565b634e487b7160e01b600052601160045260246000fd5b6000828210156133be576133be613396565b500390565b634e487b7160e01b600052601260045260246000fd5b6000826133e8576133e86133c3565b500690565b600081600019048311821515161561340757613407613396565b500290565b60008261341b5761341b6133c3565b500490565b6000821982111561343357613433613396565b500190565b6001600160a01b038116811461303c57600080fd5b60006020828403121561345f57600080fd5b8135611ebc81613438565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156134a3576134a361346a565b60405290565b6040516020810167ffffffffffffffff811182821017156134a3576134a361346a565b60405160a0810167ffffffffffffffff811182821017156134a3576134a361346a565b60405160e0810167ffffffffffffffff811182821017156134a3576134a361346a565b67ffffffffffffffff8116811461303c57600080fd5b600067ffffffffffffffff808411156135435761354361346a565b604051601f8501601f19908116603f0116810190828211818310171561356b5761356b61346a565b8160405280935085815286868601111561358457600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126135af57600080fd5b611ebc83833560208501613528565b6000606082840312156135d057600080fd5b6135d8613480565b9050813567ffffffffffffffff808211156135f257600080fd5b6135fe8583860161359e565b8352602084013591508082111561361457600080fd5b6136208583860161359e565b6020840152604084013591508082111561363957600080fd5b506136468482850161359e565b60408301525092915050565b6000818303606081121561366557600080fd5b61366d613480565b9150823567ffffffffffffffff8082111561368757600080fd5b818501915085601f83011261369b57600080fd5b6136aa86833560208501613528565b84526020601f19840112156136be57600080fd5b6136c66134a9565b9250602085013591506136d882613512565b81835282602085015260408501359250808311156136f557600080fd5b5050613646848285016135be565b600081360361016081121561371757600080fd5b61371f6134cc565b833561372a81613438565b815260e0601f198301121561373e57600080fd5b6137466134ef565b9150602084013561375681613512565b8083525060408401356020830152606084013560408301526080840135606083015260a0840135608083015260c084013560a083015260e084013561379a81613512565b60c083015260208101919091526101008301359067ffffffffffffffff8211156137c357600080fd5b6137cf36838601613652565b604082015261012084013560608201526101409093013560808401525090919050565b600081356109d281613512565b60008235605e1983360301811261381557600080fd5b9190910192915050565b6000808335601e1984360301811261383657600080fd5b83018035915067ffffffffffffffff82111561385157600080fd5b602001915036819003821315612bfb57600080fd5b600181811c9082168061387a57607f821691505b602082108114156105c757634e487b7160e01b600052602260045260246000fd5b601f82111561231a57600081815260208120601f850160051c810160208610156138c25750805b601f850160051c820191505b818110156138e1578281556001016138ce565b505050505050565b81356138f481613512565b815467ffffffffffffffff191667ffffffffffffffff8216178255505050565b67ffffffffffffffff83111561392c5761392c61346a565b6139408361393a8354613866565b8361389b565b6000601f841160018114613974576000851561395c5750838201355b600019600387901b1c1916600186901b17835561074c565b600083815260209020601f19861690835b828110156139a55786850135825560209485019460019092019101613985565b50868210156139c25760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6139de828361381f565b67ffffffffffffffff8111156139f6576139f661346a565b613a0a81613a048554613866565b8561389b565b6000601f821160018114613a3e5760008315613a265750838201355b600019600385901b1c1916600184901b178555613a98565b600085815260209020601f19841690835b82811015613a6f5786850135825560209485019460019092019101613a4f565b5084821015613a8c5760001960f88660031b161c19848701351681555b505060018360011b0185555b50505050613aa9602083018361381f565b613ab7818360018601613914565b5050613ac6604083018361381f565b61074e818360028601613914565b613ade828361381f565b67ffffffffffffffff811115613af657613af661346a565b613b0481613a048554613866565b6000601f821160018114613b385760008315613b205750838201355b600019600385901b1c1916600184901b178555613b92565b600085815260209020601f19841690835b82811015613b695786850135825560209485019460019092019101613b49565b5084821015613b865760001960f88660031b161c19848701351681555b505060018360011b0185555b50505050613ba660208301600183016138e9565b6109bb613bb660408401846137ff565b600283016139d4565b8135613bca81613438565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff19835416178255506020820135613bff81613512565b60018201805467ffffffffffffffff191667ffffffffffffffff83161790555060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155613c83613c6060e084016137f2565b6007830167ffffffffffffffff821667ffffffffffffffff198254161781555050565b613c9d613c946101008401846137ff565b60088301613ad4565b610120820135600d820155610140820135600e8201555050565b82815261010081018235613cca81613512565b67ffffffffffffffff8082166020850152602085013560408501526040850135606085015260608501356080850152608085013560a085015260a085013560c085015260c08501359150613d1d82613512565b80821660e085015250509392505050565b634e487b7160e01b600052600160045260246000fd5b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215613d8c57600080fd5b81518015158114611ebc57600080fd5b600061ffff83811690831681811015613db757613db7613396565b039392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220f8596c0debde8f4c5f106b1a1a26548b502491cf402f7c606b84ced06c2d466f64736f6c63430008080033", + "numDeployments": 2, + "solcInputHash": "1f43413075cc2b565de996acf5469041", + "metadata": "{\"compiler\":{\"version\":\"0.8.8+commit.dddeac2f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token_\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"repairRewardPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"maxNumberOfSlashes\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"slashCriterion\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"slashPercentage\",\"type\":\"uint8\"}],\"internalType\":\"struct CollateralConfig\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"downtime\",\"type\":\"uint8\"}],\"internalType\":\"struct ProofConfig\",\"name\":\"proofs\",\"type\":\"tuple\"}],\"internalType\":\"struct MarketplaceConfig\",\"name\":\"configuration\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"ProofSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"SlotFilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"SlotFreed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"}],\"name\":\"StorageRequested\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"repairRewardPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"maxNumberOfSlashes\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"slashCriterion\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"slashPercentage\",\"type\":\"uint8\"}],\"internalType\":\"struct CollateralConfig\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"downtime\",\"type\":\"uint8\"}],\"internalType\":\"struct ProofConfig\",\"name\":\"proofs\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"fillSlot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"freeSlot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"getActiveSlot\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"cid\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"totalChunks\",\"type\":\"uint64\"}],\"internalType\":\"struct Erasure\",\"name\":\"erasure\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"u\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"internalType\":\"struct PoR\",\"name\":\"por\",\"type\":\"tuple\"}],\"internalType\":\"struct Content\",\"name\":\"content\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct Request\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"internalType\":\"struct Marketplace.ActiveSlot\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getChallenge\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"getHost\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getPointer\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"getRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"cid\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"totalChunks\",\"type\":\"uint64\"}],\"internalType\":\"struct Erasure\",\"name\":\"erasure\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"u\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"internalType\":\"struct PoR\",\"name\":\"por\",\"type\":\"tuple\"}],\"internalType\":\"struct Content\",\"name\":\"content\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct Request\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"isProofRequired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"},{\"internalType\":\"Periods.Period\",\"name\":\"period\",\"type\":\"uint256\"}],\"name\":\"markProofAsMissing\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"missingProofs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"myRequests\",\"outputs\":[{\"internalType\":\"RequestId[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mySlots\",\"outputs\":[{\"internalType\":\"SlotId[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"requestEnd\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"requestState\",\"outputs\":[{\"internalType\":\"enum RequestState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"cid\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"totalChunks\",\"type\":\"uint64\"}],\"internalType\":\"struct Erasure\",\"name\":\"erasure\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"u\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"internalType\":\"struct PoR\",\"name\":\"por\",\"type\":\"tuple\"}],\"internalType\":\"struct Content\",\"name\":\"content\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct Request\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"requestStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"}],\"name\":\"slotState\",\"outputs\":[{\"internalType\":\"enum SlotState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"submitProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"willProofBeRequired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"withdrawFunds(bytes32)\":{\"details\":\"Request must be expired, must be in RequestState.New, and the transaction must originate from the depositer address.\",\"params\":{\"requestId\":\"the id of the request\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"withdrawFunds(bytes32)\":{\"notice\":\"Withdraws storage request funds back to the client that deposited them.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Marketplace.sol\":\"Marketplace\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"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/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xc3ff3f5c4584e1d9a483ad7ced51ab64523201f4e3d3c65293e4ca8aeb77a961\",\"license\":\"MIT\"},\"contracts/Configuration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nstruct MarketplaceConfig {\\n CollateralConfig collateral;\\n ProofConfig proofs;\\n}\\n\\nstruct CollateralConfig {\\n /// @dev percentage of remaining collateral slot after it has been freed\\n /// (equivalent to `collateral - (collateral*maxNumberOfSlashes*slashPercentage)/100`)\\n /// TODO: to be aligned more closely with actual cost of repair once bandwidth incentives are known,\\n /// see https://github.com/codex-storage/codex-contracts-eth/pull/47#issuecomment-1465511949.\\n uint8 repairRewardPercentage;\\n\\n uint8 maxNumberOfSlashes; // frees slot when the number of slashing reaches this value\\n uint16 slashCriterion; // amount of proofs missed that lead to slashing\\n uint8 slashPercentage; // percentage of the collateral that is slashed\\n}\\n\\nstruct ProofConfig {\\n uint256 period; // proofs requirements are calculated per period (in seconds)\\n uint256 timeout; // mark proofs as missing before the timeout (in seconds)\\n uint8 downtime; // ignore this much recent blocks for proof requirements\\n}\\n\",\"keccak256\":\"0x355b9cd03f5ffadd52cb07c64934bb823bfebced18f4cec9e714326dfee152fc\",\"license\":\"MIT\"},\"contracts/Marketplace.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"./Configuration.sol\\\";\\nimport \\\"./Requests.sol\\\";\\nimport \\\"./Proofs.sol\\\";\\nimport \\\"./StateRetrieval.sol\\\";\\n\\ncontract Marketplace is Proofs, StateRetrieval {\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using Requests for Request;\\n\\n IERC20 public immutable token;\\n MarketplaceConfig public config;\\n\\n mapping(RequestId => Request) private _requests;\\n mapping(RequestId => RequestContext) private _requestContexts;\\n mapping(SlotId => Slot) internal _slots;\\n\\n MarketplaceTotals internal _marketplaceTotals;\\n\\n struct RequestContext {\\n RequestState state;\\n uint256 slotsFilled;\\n uint256 startedAt;\\n uint256 endsAt;\\n }\\n\\n struct Slot {\\n SlotState state;\\n RequestId requestId;\\n uint256 slotIndex;\\n /// @notice Tracks the current amount of host's collateral that is to be payed out at the end of Slot's lifespan.\\n /// @dev When Slot is filled, the collateral is collected in amount of request.ask.collateral\\n /// @dev When Host is slashed for missing a proof the slashed amount is reflected in this variable\\n uint256 currentCollateral;\\n address host;\\n }\\n\\n struct ActiveSlot {\\n Request request;\\n uint256 slotIndex;\\n }\\n\\n constructor(\\n IERC20 token_,\\n MarketplaceConfig memory configuration\\n ) Proofs(configuration.proofs) {\\n token = token_;\\n\\n require(\\n configuration.collateral.repairRewardPercentage <= 100,\\n \\\"Must be less than 100\\\"\\n );\\n require(\\n configuration.collateral.slashPercentage <= 100,\\n \\\"Must be less than 100\\\"\\n );\\n require(\\n configuration.collateral.maxNumberOfSlashes *\\n configuration.collateral.slashPercentage <=\\n 100,\\n \\\"Maximum slashing exceeds 100%\\\"\\n );\\n config = configuration;\\n }\\n\\n function requestStorage(Request calldata request) public {\\n require(request.client == msg.sender, \\\"Invalid client address\\\");\\n\\n RequestId id = request.id();\\n require(_requests[id].client == address(0), \\\"Request already exists\\\");\\n\\n _requests[id] = request;\\n _requestContexts[id].endsAt = block.timestamp + request.ask.duration;\\n\\n _addToMyRequests(request.client, id);\\n\\n uint256 amount = request.price();\\n _marketplaceTotals.received += amount;\\n _transferFrom(msg.sender, amount);\\n\\n emit StorageRequested(id, request.ask, request.expiry);\\n }\\n\\n function fillSlot(\\n RequestId requestId,\\n uint256 slotIndex,\\n bytes calldata proof\\n ) public requestIsKnown(requestId) {\\n Request storage request = _requests[requestId];\\n require(slotIndex < request.ask.slots, \\\"Invalid slot\\\");\\n\\n SlotId slotId = Requests.slotId(requestId, slotIndex);\\n Slot storage slot = _slots[slotId];\\n slot.requestId = requestId;\\n slot.slotIndex = slotIndex;\\n\\n require(slotState(slotId) == SlotState.Free, \\\"Slot is not free\\\");\\n\\n _startRequiringProofs(slotId, request.ask.proofProbability);\\n submitProof(slotId, proof);\\n\\n slot.host = msg.sender;\\n slot.state = SlotState.Filled;\\n RequestContext storage context = _requestContexts[requestId];\\n context.slotsFilled += 1;\\n\\n // Collect collateral\\n uint256 collateralAmount = request.ask.collateral;\\n _transferFrom(msg.sender, collateralAmount);\\n _marketplaceTotals.received += collateralAmount;\\n slot.currentCollateral = collateralAmount;\\n\\n _addToMySlots(slot.host, slotId);\\n\\n emit SlotFilled(requestId, slotIndex);\\n if (context.slotsFilled == request.ask.slots) {\\n context.state = RequestState.Started;\\n context.startedAt = block.timestamp;\\n emit RequestFulfilled(requestId);\\n }\\n }\\n\\n function freeSlot(SlotId slotId) public slotIsNotFree(slotId) {\\n Slot storage slot = _slots[slotId];\\n require(slot.host == msg.sender, \\\"Slot filled by other host\\\");\\n SlotState state = slotState(slotId);\\n require(state != SlotState.Paid, \\\"Already paid\\\");\\n\\n if (state == SlotState.Finished) {\\n _payoutSlot(slot.requestId, slotId);\\n } else if (state == SlotState.Failed) {\\n _removeFromMySlots(msg.sender, slotId);\\n } else if (state == SlotState.Filled) {\\n _forciblyFreeSlot(slotId);\\n }\\n }\\n\\n function markProofAsMissing(SlotId slotId, Period period) public {\\n require(slotState(slotId) == SlotState.Filled, \\\"Slot not accepting proofs\\\");\\n _markProofAsMissing(slotId, period);\\n Slot storage slot = _slots[slotId];\\n Request storage request = _requests[slot.requestId];\\n\\n if (missingProofs(slotId) % config.collateral.slashCriterion == 0) {\\n uint256 slashedAmount = (request.ask.collateral *\\n config.collateral.slashPercentage) / 100;\\n slot.currentCollateral -= slashedAmount;\\n if (\\n missingProofs(slotId) / config.collateral.slashCriterion >=\\n config.collateral.maxNumberOfSlashes\\n ) {\\n // When the number of slashings is at or above the allowed amount,\\n // free the slot.\\n _forciblyFreeSlot(slotId);\\n }\\n }\\n }\\n\\n function _forciblyFreeSlot(SlotId slotId) internal {\\n Slot storage slot = _slots[slotId];\\n RequestId requestId = slot.requestId;\\n RequestContext storage context = _requestContexts[requestId];\\n\\n _removeFromMySlots(slot.host, slotId);\\n\\n uint256 slotIndex = slot.slotIndex;\\n delete _slots[slotId];\\n context.slotsFilled -= 1;\\n emit SlotFreed(requestId, slotIndex);\\n _resetMissingProofs(slotId);\\n\\n Request storage request = _requests[requestId];\\n uint256 slotsLost = request.ask.slots - context.slotsFilled;\\n if (\\n slotsLost > request.ask.maxSlotLoss &&\\n context.state == RequestState.Started\\n ) {\\n context.state = RequestState.Failed;\\n context.endsAt = block.timestamp - 1;\\n emit RequestFailed(requestId);\\n\\n // TODO: send client remaining funds\\n }\\n }\\n\\n function _payoutSlot(\\n RequestId requestId,\\n SlotId slotId\\n ) private requestIsKnown(requestId) {\\n RequestContext storage context = _requestContexts[requestId];\\n Request storage request = _requests[requestId];\\n context.state = RequestState.Finished;\\n _removeFromMyRequests(request.client, requestId);\\n Slot storage slot = _slots[slotId];\\n\\n _removeFromMySlots(slot.host, slotId);\\n\\n uint256 amount = _requests[requestId].pricePerSlot() +\\n slot.currentCollateral;\\n _marketplaceTotals.sent += amount;\\n slot.state = SlotState.Paid;\\n assert(token.transfer(slot.host, amount));\\n }\\n\\n /// @notice Withdraws storage request funds back to the client that deposited them.\\n /// @dev Request must be expired, must be in RequestState.New, and the transaction must originate from the depositer address.\\n /// @param requestId the id of the request\\n function withdrawFunds(RequestId requestId) public {\\n Request storage request = _requests[requestId];\\n require(block.timestamp > request.expiry, \\\"Request not yet timed out\\\");\\n require(request.client == msg.sender, \\\"Invalid client address\\\");\\n RequestContext storage context = _requestContexts[requestId];\\n require(context.state == RequestState.New, \\\"Invalid state\\\");\\n\\n // Update request state to Cancelled. Handle in the withdraw transaction\\n // as there needs to be someone to pay for the gas to update the state\\n context.state = RequestState.Cancelled;\\n _removeFromMyRequests(request.client, requestId);\\n\\n emit RequestCancelled(requestId);\\n\\n // TODO: To be changed once we start paying out hosts for the time they\\n // fill a slot. The amount that we paid to hosts will then have to be\\n // deducted from the price.\\n uint256 amount = request.price();\\n _marketplaceTotals.sent += amount;\\n assert(token.transfer(msg.sender, amount));\\n }\\n\\n function getActiveSlot(\\n SlotId slotId\\n ) public view slotIsNotFree(slotId) returns (ActiveSlot memory) {\\n Slot storage slot = _slots[slotId];\\n ActiveSlot memory activeSlot;\\n activeSlot.request = _requests[slot.requestId];\\n activeSlot.slotIndex = slot.slotIndex;\\n return activeSlot;\\n }\\n\\n modifier requestIsKnown(RequestId requestId) {\\n require(_requests[requestId].client != address(0), \\\"Unknown request\\\");\\n _;\\n }\\n\\n function getRequest(\\n RequestId requestId\\n ) public view requestIsKnown(requestId) returns (Request memory) {\\n return _requests[requestId];\\n }\\n\\n modifier slotIsNotFree(SlotId slotId) {\\n require(_slots[slotId].state != SlotState.Free, \\\"Slot is free\\\");\\n _;\\n }\\n\\n function requestEnd(RequestId requestId) public view returns (uint256) {\\n uint256 end = _requestContexts[requestId].endsAt;\\n RequestState state = requestState(requestId);\\n if (state == RequestState.New || state == RequestState.Started) {\\n return end;\\n } else {\\n return Math.min(end, block.timestamp - 1);\\n }\\n }\\n\\n function getHost(SlotId slotId) public view returns (address) {\\n return _slots[slotId].host;\\n }\\n\\n function requestState(\\n RequestId requestId\\n ) public view requestIsKnown(requestId) returns (RequestState) {\\n RequestContext storage context = _requestContexts[requestId];\\n if (\\n context.state == RequestState.New &&\\n block.timestamp > _requests[requestId].expiry\\n ) {\\n return RequestState.Cancelled;\\n } else if (\\n context.state == RequestState.Started && block.timestamp > context.endsAt\\n ) {\\n return RequestState.Finished;\\n } else {\\n return context.state;\\n }\\n }\\n\\n function slotState(SlotId slotId) public view override returns (SlotState) {\\n Slot storage slot = _slots[slotId];\\n if (RequestId.unwrap(slot.requestId) == 0) {\\n return SlotState.Free;\\n }\\n RequestState reqState = requestState(slot.requestId);\\n if (slot.state == SlotState.Paid) {\\n return SlotState.Paid;\\n }\\n if (reqState == RequestState.Cancelled) {\\n return SlotState.Finished;\\n }\\n if (reqState == RequestState.Finished) {\\n return SlotState.Finished;\\n }\\n if (reqState == RequestState.Failed) {\\n return SlotState.Failed;\\n }\\n return slot.state;\\n }\\n\\n function _transferFrom(address sender, uint256 amount) internal {\\n address receiver = address(this);\\n require(token.transferFrom(sender, receiver, amount), \\\"Transfer failed\\\");\\n }\\n\\n event StorageRequested(RequestId requestId, Ask ask, uint256 expiry);\\n event RequestFulfilled(RequestId indexed requestId);\\n event RequestFailed(RequestId indexed requestId);\\n event SlotFilled(\\n RequestId indexed requestId,\\n uint256 slotIndex\\n );\\n event SlotFreed(\\n RequestId indexed requestId,\\n uint256 slotIndex\\n );\\n event RequestCancelled(RequestId indexed requestId);\\n\\n struct MarketplaceTotals {\\n uint256 received;\\n uint256 sent;\\n }\\n}\\n\",\"keccak256\":\"0xaf91b6c170f1801ca161831001b81bd68e9a6357c4709bc286868145bb64f636\",\"license\":\"MIT\"},\"contracts/Periods.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\ncontract Periods {\\n type Period is uint256;\\n\\n uint256 internal immutable _secondsPerPeriod;\\n\\n constructor(uint256 secondsPerPeriod) {\\n _secondsPerPeriod = secondsPerPeriod;\\n }\\n\\n function _periodOf(uint256 timestamp) internal view returns (Period) {\\n return Period.wrap(timestamp / _secondsPerPeriod);\\n }\\n\\n function _blockPeriod() internal view returns (Period) {\\n return _periodOf(block.timestamp);\\n }\\n\\n function _nextPeriod(Period period) internal pure returns (Period) {\\n return Period.wrap(Period.unwrap(period) + 1);\\n }\\n\\n function _periodStart(Period period) internal view returns (uint256) {\\n return Period.unwrap(period) * _secondsPerPeriod;\\n }\\n\\n function _periodEnd(Period period) internal view returns (uint256) {\\n return _periodStart(_nextPeriod(period));\\n }\\n\\n function _isBefore(Period a, Period b) internal pure returns (bool) {\\n return Period.unwrap(a) < Period.unwrap(b);\\n }\\n\\n function _isAfter(Period a, Period b) internal pure returns (bool) {\\n return _isBefore(b, a);\\n }\\n}\\n\",\"keccak256\":\"0xf5c816a69a705fd84bd3e43490ea32e8cc5bec05363b7c2deb32665519d0bfe2\",\"license\":\"MIT\"},\"contracts/Proofs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"./Configuration.sol\\\";\\nimport \\\"./Requests.sol\\\";\\nimport \\\"./Periods.sol\\\";\\n\\nabstract contract Proofs is Periods {\\n ProofConfig private _config;\\n\\n constructor(ProofConfig memory config) Periods(config.period) {\\n require(block.number > 256, \\\"Insufficient block height\\\");\\n _config = config;\\n }\\n\\n mapping(SlotId => uint256) private _slotStarts;\\n mapping(SlotId => uint256) private _probabilities;\\n mapping(SlotId => uint256) private _missed;\\n mapping(SlotId => mapping(Period => bool)) private _received;\\n mapping(SlotId => mapping(Period => bool)) private _missing;\\n\\n function slotState(SlotId id) public view virtual returns (SlotState);\\n\\n function missingProofs(SlotId slotId) public view returns (uint256) {\\n return _missed[slotId];\\n }\\n\\n function _resetMissingProofs(SlotId slotId) internal {\\n _missed[slotId] = 0;\\n }\\n\\n function _startRequiringProofs(SlotId id, uint256 probability) internal {\\n _slotStarts[id] = block.timestamp;\\n _probabilities[id] = probability;\\n }\\n\\n function _getPointer(SlotId id, Period period) internal view returns (uint8) {\\n uint256 blockNumber = block.number % 256;\\n uint256 periodNumber = Period.unwrap(period) % 256;\\n uint256 idOffset = uint256(SlotId.unwrap(id)) % 256;\\n uint256 pointer = (blockNumber + periodNumber + idOffset) % 256;\\n return uint8(pointer);\\n }\\n\\n function getPointer(SlotId id) public view returns (uint8) {\\n return _getPointer(id, _blockPeriod());\\n }\\n\\n function _getChallenge(uint8 pointer) internal view returns (bytes32) {\\n bytes32 hash = blockhash(block.number - 1 - pointer);\\n assert(uint256(hash) != 0);\\n return keccak256(abi.encode(hash));\\n }\\n\\n function _getChallenge(\\n SlotId id,\\n Period period\\n ) internal view returns (bytes32) {\\n return _getChallenge(_getPointer(id, period));\\n }\\n\\n function getChallenge(SlotId id) public view returns (bytes32) {\\n return _getChallenge(id, _blockPeriod());\\n }\\n\\n function _getProofRequirement(\\n SlotId id,\\n Period period\\n ) internal view returns (bool isRequired, uint8 pointer) {\\n SlotState state = slotState(id);\\n Period start = _periodOf(_slotStarts[id]);\\n if (state != SlotState.Filled || !_isAfter(period, start)) {\\n return (false, 0);\\n }\\n pointer = _getPointer(id, period);\\n bytes32 challenge = _getChallenge(pointer);\\n uint256 probability = (_probabilities[id] * (256 - _config.downtime)) / 256;\\n isRequired = probability == 0 || uint256(challenge) % probability == 0;\\n }\\n\\n function _isProofRequired(\\n SlotId id,\\n Period period\\n ) internal view returns (bool) {\\n bool isRequired;\\n uint8 pointer;\\n (isRequired, pointer) = _getProofRequirement(id, period);\\n return isRequired && pointer >= _config.downtime;\\n }\\n\\n function isProofRequired(SlotId id) public view returns (bool) {\\n return _isProofRequired(id, _blockPeriod());\\n }\\n\\n function willProofBeRequired(SlotId id) public view returns (bool) {\\n bool isRequired;\\n uint8 pointer;\\n (isRequired, pointer) = _getProofRequirement(id, _blockPeriod());\\n return isRequired && pointer < _config.downtime;\\n }\\n\\n function submitProof(SlotId id, bytes calldata proof) public {\\n require(proof.length > 0, \\\"Invalid proof\\\"); // TODO: replace by actual check\\n require(!_received[id][_blockPeriod()], \\\"Proof already submitted\\\");\\n _received[id][_blockPeriod()] = true;\\n emit ProofSubmitted(id, proof);\\n }\\n\\n function _markProofAsMissing(SlotId id, Period missedPeriod) internal {\\n uint256 end = _periodEnd(missedPeriod);\\n require(end < block.timestamp, \\\"Period has not ended yet\\\");\\n require(block.timestamp < end + _config.timeout, \\\"Validation timed out\\\");\\n require(!_received[id][missedPeriod], \\\"Proof was submitted, not missing\\\");\\n require(_isProofRequired(id, missedPeriod), \\\"Proof was not required\\\");\\n require(!_missing[id][missedPeriod], \\\"Proof already marked as missing\\\");\\n _missing[id][missedPeriod] = true;\\n _missed[id] += 1;\\n }\\n\\n event ProofSubmitted(SlotId id, bytes proof);\\n}\\n\",\"keccak256\":\"0x3ffba023dfb5aff8f3367768586fbad12e7385fb3855c9f06871e0b5a2fc1ec4\",\"license\":\"MIT\"},\"contracts/Requests.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\ntype RequestId is bytes32;\\ntype SlotId is bytes32;\\n\\nstruct Request {\\n address client;\\n Ask ask;\\n Content content;\\n uint256 expiry; // timestamp as seconds since unix epoch at which this request expires\\n bytes32 nonce; // random nonce to differentiate between similar requests\\n}\\n\\nstruct Ask {\\n uint64 slots; // the number of requested slots\\n uint256 slotSize; // amount of storage per slot (in number of bytes)\\n uint256 duration; // how long content should be stored (in seconds)\\n uint256 proofProbability; // how often storage proofs are required\\n uint256 reward; // amount of tokens paid per second per slot to hosts\\n uint256 collateral; // amount of tokens required to be deposited by the hosts in order to fill the slot\\n uint64 maxSlotLoss; // Max slots that can be lost without data considered to be lost\\n}\\n\\nstruct Content {\\n string cid; // content id (if part of a larger set, the chunk cid)\\n Erasure erasure; // Erasure coding attributes\\n PoR por; // Proof of Retrievability parameters\\n}\\n\\nstruct Erasure {\\n uint64 totalChunks; // the total number of chunks in the larger data set\\n}\\n\\nstruct PoR {\\n bytes u; // parameters u_1..u_s\\n bytes publicKey; // public key\\n bytes name; // random name\\n}\\n\\nenum RequestState {\\n New, // [default] waiting to fill slots\\n Started, // all slots filled, accepting regular proofs\\n Cancelled, // not enough slots filled before expiry\\n Finished, // successfully completed\\n Failed // too many nodes have failed to provide proofs, data lost\\n}\\n\\nenum SlotState {\\n Free, // [default] not filled yet, or host has vacated the slot\\n Filled, // host has filled slot\\n Finished, // successfully completed\\n Failed, // the request has failed\\n Paid // host has been paid\\n}\\n\\nlibrary Requests {\\n function id(Request memory request) internal pure returns (RequestId) {\\n return RequestId.wrap(keccak256(abi.encode(request)));\\n }\\n\\n function slotId(\\n RequestId requestId,\\n uint256 slotIndex\\n ) internal pure returns (SlotId) {\\n return SlotId.wrap(keccak256(abi.encode(requestId, slotIndex)));\\n }\\n\\n function toRequestIds(\\n bytes32[] memory ids\\n ) internal pure returns (RequestId[] memory result) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := ids\\n }\\n }\\n\\n function toSlotIds(\\n bytes32[] memory ids\\n ) internal pure returns (SlotId[] memory result) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := ids\\n }\\n }\\n\\n function pricePerSlot(\\n Request memory request\\n ) internal pure returns (uint256) {\\n return request.ask.duration * request.ask.reward;\\n }\\n\\n function price(Request memory request) internal pure returns (uint256) {\\n return request.ask.slots * pricePerSlot(request);\\n }\\n}\\n\",\"keccak256\":\"0x84d4ed812857885c70457625e815abf47e53b41ef4d06d5decc9fa13d82ed45c\",\"license\":\"MIT\"},\"contracts/StateRetrieval.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"./Requests.sol\\\";\\n\\ncontract StateRetrieval {\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using Requests for bytes32[];\\n\\n mapping(address => EnumerableSet.Bytes32Set) private _requestsPerClient;\\n mapping(address => EnumerableSet.Bytes32Set) private _slotsPerHost;\\n\\n function myRequests() public view returns (RequestId[] memory) {\\n return _requestsPerClient[msg.sender].values().toRequestIds();\\n }\\n\\n function mySlots() public view returns (SlotId[] memory) {\\n return _slotsPerHost[msg.sender].values().toSlotIds();\\n }\\n\\n function _hasSlots(address host) internal view returns (bool) {\\n return _slotsPerHost[host].length() > 0;\\n }\\n\\n function _addToMyRequests(address client, RequestId requestId) internal {\\n _requestsPerClient[client].add(RequestId.unwrap(requestId));\\n }\\n\\n function _addToMySlots(address host, SlotId slotId) internal {\\n _slotsPerHost[host].add(SlotId.unwrap(slotId));\\n }\\n\\n function _removeFromMyRequests(address client, RequestId requestId) internal {\\n _requestsPerClient[client].remove(RequestId.unwrap(requestId));\\n }\\n\\n function _removeFromMySlots(address host, SlotId slotId) internal {\\n _slotsPerHost[host].remove(SlotId.unwrap(slotId));\\n }\\n}\\n\",\"keccak256\":\"0xe29275c3ff31874cac3b8ecf67c59502e9fdefb956142278c58ee3aa956801fd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b506040516200401d3803806200401d833981016040819052620000349162000373565b602081015180516080526101004311620000955760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420626c6f636b206865696768740000000000000060448201526064015b60405180910390fd5b80516000556020810151600155604001516002805460ff191660ff928316179055606083901b6001600160601b03191660a0528151516064911611156200011f5760405162461bcd60e51b815260206004820152601560248201527f4d757374206265206c657373207468616e20313030000000000000000000000060448201526064016200008c565b606481600001516060015160ff1611156200017d5760405162461bcd60e51b815260206004820152601560248201527f4d757374206265206c657373207468616e20313030000000000000000000000060448201526064016200008c565b8051606081015160209091015160649162000198916200044f565b60ff161115620001eb5760405162461bcd60e51b815260206004820152601d60248201527f4d6178696d756d20736c617368696e672065786365656473203130302500000060448201526064016200008c565b80518051600a805460208085015160408087015160609097015160ff9081166401000000000260ff60201b1961ffff90991662010000029890981664ffffff0000199382166101000261ffff199096169782169790971794909417919091169490941794909417909155928201518051600b5591820151600c550151600d80549190921660ff19919091161790555062000487565b604080519081016001600160401b0381118282101715620002b157634e487b7160e01b600052604160045260246000fd5b60405290565b604051608081016001600160401b0381118282101715620002b157634e487b7160e01b600052604160045260246000fd5b805160ff81168114620002fa57600080fd5b919050565b6000606082840312156200031257600080fd5b604051606081016001600160401b03811182821017156200034357634e487b7160e01b600052604160045260246000fd5b806040525080915082518152602083015160208201526200036760408401620002e8565b60408201525092915050565b6000808284036101008112156200038957600080fd5b83516001600160a01b0381168114620003a157600080fd5b9250601f190160e0811215620003b657600080fd5b620003c062000280565b6080821215620003cf57600080fd5b620003d9620002b7565b9150620003e960208601620002e8565b8252620003f960408601620002e8565b6020830152606085015161ffff811681146200041457600080fd5b60408301526200042760808601620002e8565b60608301528181526200043e8660a08701620002ff565b602082015280925050509250929050565b600060ff821660ff84168160ff04811182151516156200047f57634e487b7160e01b600052601160045260246000fd5b029392505050565b60805160a05160601c613b51620004cc6000396000818161044201528181611222015281816121a9015261279c01526000818161299e0152612a9f0152613b516000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80636e2b54ee116100d8578063b396dc791161008c578063f752196b11610066578063f752196b146103fd578063fb1e61ca1461041d578063fc0c546a1461043d57600080fd5b8063b396dc79146103b7578063be5cdc48146103d7578063c0cc4add146103ea57600080fd5b80639777b72c116100bd5780639777b72c14610379578063a29c29a414610381578063a3a0807e1461039457600080fd5b80636e2b54ee146102a157806379502c55146102b457600080fd5b80634641dce61161012f5780636368a471116101145780636368a47114610237578063645116d81461024a5780636b00c8cf1461025d57600080fd5b80634641dce6146101fd5780635da738351461022257600080fd5b806308695fcd1161016057806308695fcd146101c25780630eb6c86f146101d7578063458d2bf1146101ea57600080fd5b806302fa8e651461017c57806305b90773146101a2575b600080fd5b61018f61018a366004612d16565b610464565b6040519081526020015b60405180910390f35b6101b56101b0366004612d16565b6104db565b6040516101999190612d66565b6101d56101d0366004612d79565b6105cd565b005b6101d56101e5366004612d9b565b610720565b61018f6101f8366004612d16565b6108da565b61021061020b366004612d16565b6108f3565b60405160ff9091168152602001610199565b61022a610906565b6040516101999190612dd7565b6101d5610245366004612e5d565b61092d565b6101d5610258366004612eb0565b610c0b565b61028961026b366004612d16565b6000908152601060205260409020600401546001600160a01b031690565b6040516001600160a01b039091168152602001610199565b6101d56102af366004612d16565b610d41565b60408051608081018252600a5460ff80821683526101008204811660208085019190915261ffff6201000084041684860152640100000000909204811660608085019190915284519081018552600b548152600c5492810192909252600d5416928101929092526103229182565b60408051835160ff90811682526020808601518216818401528584015161ffff1683850152606095860151821695830195909552835160808301529383015160a082015291015190911660c082015260e001610199565b61022a6112b2565b6101d561038f366004612d16565b6112d1565b6103a76103a2366004612d16565b611480565b6040519015158152602001610199565b6103ca6103c5366004612d16565b6114b5565b6040516101999190613078565b6101b56103e5366004612d16565b611885565b6103a76103f8366004612d16565b611955565b61018f61040b366004612d16565b60009081526005602052604090205490565b61043061042b366004612d16565b611968565b60405161019991906130aa565b6102897f000000000000000000000000000000000000000000000000000000000000000081565b6000818152600f602052604081206003015481610480846104db565b9050600081600481111561049657610496612d2f565b14806104b3575060018160048111156104b1576104b1612d2f565b145b156104bf575092915050565b6104d3826104ce6001426130d3565b611d01565b949350505050565b6000818152600e602052604081205482906001600160a01b03166105385760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b60448201526064015b60405180910390fd5b6000838152600f6020526040812090815460ff16600481111561055d5761055d612d2f565b14801561057a57506000848152600e60205260409020600d015442115b156105895760029250506105c7565b6001815460ff1660048111156105a1576105a1612d2f565b1480156105b15750806003015442115b156105c05760039250506105c7565b5460ff1691505b50919050565b60016105d883611885565b60048111156105e9576105e9612d2f565b146106365760405162461bcd60e51b815260206004820152601960248201527f536c6f74206e6f7420616363657074696e672070726f6f667300000000000000604482015260640161052f565b6106408282611d19565b600082815260106020908152604080832060018101548452600e909252909120600a5461ffff62010000909104166106848560009081526005602052604090205490565b61068e9190613100565b61071a57600a5460068201546000916064916106b591640100000000900460ff1690613114565b6106bf9190613133565b9050808360030160008282546106d591906130d3565b9091555050600a54600086815260056020526040902054610100820460ff169162010000900461ffff169061070a9190613133565b106107185761071885611f46565b505b50505050565b3361072e602083018361315c565b6001600160a01b0316146107845760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b600061079761079283613412565b6120e5565b6000818152600e60205260409020549091506001600160a01b0316156107ff5760405162461bcd60e51b815260206004820152601660248201527f5265717565737420616c72656164792065786973747300000000000000000000604482015260640161052f565b6000818152600e60205260409020829061081982826138d2565b5061082a90506060830135426139ca565b6000828152600f6020908152604090912060030191909155610858906108529084018461315c565b82612115565b600061086b61086684613412565b61213c565b9050806011600001600082825461088291906139ca565b9091555061089290503382612161565b7f5fdb86c365a247a4d97dcbcc5c3abde9d6e3e2de26273f3fda8eef5073b9a96c82846020018561012001356040516108cd939291906139e2565b60405180910390a1505050565b60006108ed826108e8612273565b61227e565b92915050565b60006108ed82610901612273565b612292565b33600090815260096020526040902060609061092890610925906122f2565b90565b905090565b6000848152600e602052604090205484906001600160a01b03166109855760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000858152600e60205260409020600181015467ffffffffffffffff1685106109f05760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420736c6f740000000000000000000000000000000000000000604482015260640161052f565b604080516020808201899052818301889052825180830384018152606090920190925280519101206000906000818152601060205260408120600181018a905560028101899055919250610a4383611885565b6004811115610a5457610a54612d2f565b14610aa15760405162461bcd60e51b815260206004820152601060248201527f536c6f74206973206e6f74206672656500000000000000000000000000000000604482015260640161052f565b60048084015460008481526003602090815260408083204290559390529190912055610ace828787610c0b565b60048101805473ffffffffffffffffffffffffffffffffffffffff191633179055805460ff1916600190811782556000898152600f6020526040812080830180549193929091610b1f9084906139ca565b90915550506006840154610b333382612161565b8060116000016000828254610b4891906139ca565b9091555050600383018190556004830154610b6c906001600160a01b0316856122ff565b897ff530852268993f91008f1a1e0b09b5c813acd4188481f1fa83c33c7182e814b48a604051610b9e91815260200190565b60405180910390a26001808601549083015467ffffffffffffffff9091161415610bff57815460ff191660011782554260028301556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b80610c585760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642070726f6f6600000000000000000000000000000000000000604482015260640161052f565b600083815260066020526040812090610c6f612273565b815260208101919091526040016000205460ff1615610cd05760405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c7265616479207375626d6974746564000000000000000000604482015260640161052f565b6000838152600660205260408120600191610ce9612273565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f17d5257c85fa8a4b5a4d1f3520e38773826559199467bdce51698fce3d8cae9c8383836040516108cd93929190613a5e565b6000818152600e60205260409020600d8101544211610da25760405162461bcd60e51b815260206004820152601960248201527f52657175657374206e6f74207965742074696d6564206f757400000000000000604482015260640161052f565b80546001600160a01b03163314610dfb5760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b6000828152600f6020526040812090815460ff166004811115610e2057610e20612d2f565b14610e6d5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420737461746500000000000000000000000000000000000000604482015260640161052f565b805460ff191660021781558154610e8d906001600160a01b031684612321565b60405183907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a26040805160a0808201835284546001600160a01b03168252825160e081018452600186015467ffffffffffffffff90811682526002870154602083810191909152600388015483870152600488015460608085019190915260058901546080850152600689015494840194909452600788015490911660c0830152830152825190810183526008850180546000946111ea949388939185019290919082908290610f6190613575565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8d90613575565b8015610fda5780601f10610faf57610100808354040283529160200191610fda565b820191906000526020600020905b815481529060010190602001808311610fbd57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061102390613575565b80601f016020809104026020016040519081016040528092919081815260200182805461104f90613575565b801561109c5780601f106110715761010080835404028352916020019161109c565b820191906000526020600020905b81548152906001019060200180831161107f57829003601f168201915b505050505081526020016001820180546110b590613575565b80601f01602080910402602001604051908101604052809291908181526020018280546110e190613575565b801561112e5780601f106111035761010080835404028352916020019161112e565b820191906000526020600020905b81548152906001019060200180831161111157829003601f168201915b5050505050815260200160028201805461114790613575565b80601f016020809104026020016040519081016040528092919081815260200182805461117390613575565b80156111c05780601f10611195576101008083540402835291602001916111c0565b820191906000526020600020905b8154815290600101906020018083116111a357829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e8201548152505061213c565b9050806011600101600082825461120191906139ca565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561126e57600080fd5b505af1158015611282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a69190613a94565b61071a5761071a613ab6565b33600090815260086020526040902060609061092890610925906122f2565b806000808281526010602052604090205460ff1660048111156112f6576112f6612d2f565b14156113335760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b600082815260106020526040902060048101546001600160a01b0316331461139d5760405162461bcd60e51b815260206004820152601960248201527f536c6f742066696c6c6564206279206f7468657220686f737400000000000000604482015260640161052f565b60006113a884611885565b905060048160048111156113be576113be612d2f565b141561140c5760405162461bcd60e51b815260206004820152600c60248201527f416c726561647920706169640000000000000000000000000000000000000000604482015260640161052f565b600281600481111561142057611420612d2f565b141561143957611434826001015485612343565b61071a565b600381600481111561144d5761144d612d2f565b141561145d576114343385612824565b600181600481111561147157611471612d2f565b141561071a5761071a84611f46565b600080600061149684611491612273565b612846565b90925090508180156104d3575060025460ff9081169116109392505050565b6114bd612c06565b816000808281526010602052604090205460ff1660048111156114e2576114e2612d2f565b141561151f5760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b6000838152601060205260409020611535612c06565b6001808301546000908152600e6020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186529583015467ffffffffffffffff908116875260028401548786015260038401548787015260048401546060808901919091526005850154608089015260068501549288019290925260078401541660c08701529281019490945282519182018352600881018054919385019291829082906115e590613575565b80601f016020809104026020016040519081016040528092919081815260200182805461161190613575565b801561165e5780601f106116335761010080835404028352916020019161165e565b820191906000526020600020905b81548152906001019060200180831161164157829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff168252830152805160608101825260028401805492909301929091829082906116a790613575565b80601f01602080910402602001604051908101604052809291908181526020018280546116d390613575565b80156117205780601f106116f557610100808354040283529160200191611720565b820191906000526020600020905b81548152906001019060200180831161170357829003601f168201915b5050505050815260200160018201805461173990613575565b80601f016020809104026020016040519081016040528092919081815260200182805461176590613575565b80156117b25780601f10611787576101008083540402835291602001916117b2565b820191906000526020600020905b81548152906001019060200180831161179557829003601f168201915b505050505081526020016002820180546117cb90613575565b80601f01602080910402602001604051908101604052809291908181526020018280546117f790613575565b80156118445780601f1061181957610100808354040283529160200191611844565b820191906000526020600020905b81548152906001019060200180831161182757829003601f168201915b505050919092525050509052508152600d820154602080830191909152600e9092015460409091015290825260029092015491810191909152915050919050565b600081815260106020526040812060018101546118a55750600092915050565b60006118b482600101546104db565b90506004825460ff1660048111156118ce576118ce612d2f565b14156118de575060049392505050565b60028160048111156118f2576118f2612d2f565b1415611902575060029392505050565b600381600481111561191657611916612d2f565b1415611926575060029392505050565b600481600481111561193a5761193a612d2f565b141561194a575060039392505050565b505460ff1692915050565b60006108ed82611963612273565b612929565b611970612c26565b6000828152600e602052604090205482906001600160a01b03166119c85760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000838152600e6020908152604091829020825160a0808201855282546001600160a01b03168252845160e081018652600184015467ffffffffffffffff908116825260028501548287015260038501548288015260048501546060808401919091526005860154608084015260068601549383019390935260078501541660c0820152938201939093528351928301845260088201805491949293928501929182908290611a7690613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611aa290613575565b8015611aef5780601f10611ac457610100808354040283529160200191611aef565b820191906000526020600020905b815481529060010190602001808311611ad257829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff16825283015280516060810182526002840180549290930192909182908290611b3890613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6490613575565b8015611bb15780601f10611b8657610100808354040283529160200191611bb1565b820191906000526020600020905b815481529060010190602001808311611b9457829003601f168201915b50505050508152602001600182018054611bca90613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf690613575565b8015611c435780601f10611c1857610100808354040283529160200191611c43565b820191906000526020600020905b815481529060010190602001808311611c2657829003601f168201915b50505050508152602001600282018054611c5c90613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8890613575565b8015611cd55780601f10611caa57610100808354040283529160200191611cd5565b820191906000526020600020905b815481529060010190602001808311611cb857829003601f168201915b505050919092525050509052508152600d8201546020820152600e909101546040909101529392505050565b6000818310611d105781611d12565b825b9392505050565b6000611d248261295c565b9050428110611d755760405162461bcd60e51b815260206004820152601860248201527f506572696f6420686173206e6f7420656e646564207965740000000000000000604482015260640161052f565b600154611d8290826139ca565b4210611dd05760405162461bcd60e51b815260206004820152601460248201527f56616c69646174696f6e2074696d6564206f7574000000000000000000000000604482015260640161052f565b600083815260066020908152604080832085845290915290205460ff1615611e3a5760405162461bcd60e51b815260206004820181905260248201527f50726f6f6620776173207375626d69747465642c206e6f74206d697373696e67604482015260640161052f565b611e448383612929565b611e905760405162461bcd60e51b815260206004820152601660248201527f50726f6f6620776173206e6f7420726571756972656400000000000000000000604482015260640161052f565b600083815260076020908152604080832085845290915290205460ff1615611efa5760405162461bcd60e51b815260206004820152601f60248201527f50726f6f6620616c7265616479206d61726b6564206173206d697373696e6700604482015260640161052f565b60008381526007602090815260408083208584528252808320805460ff1916600190811790915586845260059092528220805491929091611f3c9084906139ca565b9091555050505050565b60008181526010602090815260408083206001810154808552600f90935292206004830154611f7e906001600160a01b031685612824565b6002808401546000868152601060205260408120805460ff19168155600180820183905593810182905560038101829055600401805473ffffffffffffffffffffffffffffffffffffffff191690558383018054929392909190611fe39084906130d3565b909155505060405181815283907f1d31c9f8dea6e179f6a050db117595feea8937029ea51f5168a4780be7e8f5529060200160405180910390a26000858152600560205260408120556000838152600e602052604081206001808501549082015491929161205b919067ffffffffffffffff166130d3565b600783015490915067ffffffffffffffff168111801561209057506001845460ff16600481111561208e5761208e612d2f565b145b156120dc57835460ff191660041784556120ab6001426130d3565b600385015560405185907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a25b50505050505050565b6000816040516020016120f891906130aa565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0382166000908152600860205260409020612137908261296f565b505050565b60006121478261297b565b6020830151516108ed919067ffffffffffffffff16613114565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd90606401602060405180830381600087803b1580156121ef57600080fd5b505af1158015612203573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122279190613a94565b6121375760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015260640161052f565b600061092842612997565b6000611d1261228d8484612292565b6129c3565b6000806122a161010043613100565b905060006122b161010085613100565b905060006122c161010087613100565b90506000610100826122d385876139ca565b6122dd91906139ca565b6122e79190613100565b979650505050505050565b60606000611d1283612a19565b6001600160a01b0382166000908152600960205260409020612137908261296f565b6001600160a01b03821660009081526008602052604090206121379082612a75565b6000828152600e602052604090205482906001600160a01b031661239b5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000838152600f60209081526040808320600e909252909120815460ff1916600317825580546123d4906001600160a01b031686612321565b600084815260106020526040902060048101546123fa906001600160a01b031686612824565b6003808201546000888152600e60209081526040808320815160a0808201845282546001600160a01b03168252835160e081018552600184015467ffffffffffffffff90811682526002850154828801529884015481860152600484015460608083019190915260058501546080830152600685015492820192909252600784015490981660c08901529381019690965281519283018252600881018054949661273d95909492938501929190829082906124b490613575565b80601f01602080910402602001604051908101604052809291908181526020018280546124e090613575565b801561252d5780601f106125025761010080835404028352916020019161252d565b820191906000526020600020905b81548152906001019060200180831161251057829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061257690613575565b80601f01602080910402602001604051908101604052809291908181526020018280546125a290613575565b80156125ef5780601f106125c4576101008083540402835291602001916125ef565b820191906000526020600020905b8154815290600101906020018083116125d257829003601f168201915b5050505050815260200160018201805461260890613575565b80601f016020809104026020016040519081016040528092919081815260200182805461263490613575565b80156126815780601f1061265657610100808354040283529160200191612681565b820191906000526020600020905b81548152906001019060200180831161266457829003601f168201915b5050505050815260200160028201805461269a90613575565b80601f01602080910402602001604051908101604052809291908181526020018280546126c690613575565b80156127135780601f106126e857610100808354040283529160200191612713565b820191906000526020600020905b8154815290600101906020018083116126f657829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e8201548152505061297b565b61274791906139ca565b9050806011600101600082825461275e91906139ca565b9091555050815460ff1916600490811783558083015460405163a9059cbb60e01b81526001600160a01b0391821692810192909252602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b1580156127e057600080fd5b505af11580156127f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128189190613a94565b6120dc576120dc613ab6565b6001600160a01b03821660009081526009602052604090206121379082612a75565b600080600061285485611885565b6000868152600360205260408120549192509061287090612997565b9050600182600481111561288657612886612d2f565b14158061289a57506128988582612a81565b155b156128ad57600080935093505050612922565b6128b78686612292565b925060006128c4846129c3565b600254909150600090610100906128de9060ff1682613acc565b60008a8152600460205260409020546128fb9161ffff1690613114565b6129059190613133565b905080158061291b57506129198183613100565b155b9550505050505b9250929050565b60008060006129388585612846565b9092509050818015612953575060025460ff90811690821610155b95945050505050565b60006108ed61296a83612a8b565b612a98565b6000611d128383612ac4565b602081015160808101516040909101516000916108ed91613114565b60006108ed7f000000000000000000000000000000000000000000000000000000000000000083613133565b60008060ff83166129d56001436130d3565b6129df91906130d3565b409050806129ef576129ef613ab6565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b606081600001805480602002602001604051908101604052809291908181526020018280548015612a6957602002820191906000526020600020905b815481526020019060010190808311612a55575b50505050509050919050565b6000611d128383612b13565b6000818311611d12565b60006108ed8260016139ca565b60006108ed7f000000000000000000000000000000000000000000000000000000000000000083613114565b6000818152600183016020526040812054612b0b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108ed565b5060006108ed565b60008181526001830160205260408120548015612bfc576000612b376001836130d3565b8554909150600090612b4b906001906130d3565b9050818114612bb0576000866000018281548110612b6b57612b6b613aef565b9060005260206000200154905080876000018481548110612b8e57612b8e613aef565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612bc157612bc1613b05565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108ed565b60009150506108ed565b6040518060400160405280612c19612c26565b8152602001600081525090565b6040518060a0016040528060006001600160a01b03168152602001612c956040518060e00160405280600067ffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600067ffffffffffffffff1681525090565b8152602001612ca2612cb6565b815260006020820181905260409091015290565b604051806060016040528060608152602001612ce86040518060200160405280600067ffffffffffffffff1681525090565b8152602001612d1160405180606001604052806060815260200160608152602001606081525090565b905290565b600060208284031215612d2857600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60058110612d6357634e487b7160e01b600052602160045260246000fd5b50565b60208101612d7383612d45565b91905290565b60008060408385031215612d8c57600080fd5b50508035926020909101359150565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b82016101608185031215611d1257600080fd5b6020808252825182820181905260009190848201906040850190845b81811015612e0f57835183529284019291840191600101612df3565b50909695505050505050565b60008083601f840112612e2d57600080fd5b50813567ffffffffffffffff811115612e4557600080fd5b60208301915083602082850101111561292257600080fd5b60008060008060608587031215612e7357600080fd5b8435935060208501359250604085013567ffffffffffffffff811115612e9857600080fd5b612ea487828801612e1b565b95989497509550505050565b600080600060408486031215612ec557600080fd5b83359250602084013567ffffffffffffffff811115612ee357600080fd5b612eef86828701612e1b565b9497909650939450505050565b6000815180845260005b81811015612f2257602081850181015186830182015201612f06565b81811115612f34576000602083870101525b50601f01601f19169290920160200192915050565b6000815160608452612f5e6060850182612efc565b905067ffffffffffffffff60208401515116602085015260408301518482036040860152805160608352612f956060840182612efc565b905060208201518382036020850152612fae8282612efc565b915050604082015191508281036040840152612fca8183612efc565b9695505050505050565b60006101606001600160a01b038351168452602083015167ffffffffffffffff808251166020870152602082015160408701526040820151606087015260608201516080870152608082015160a087015260a082015160c08701528060c08301511660e0870152505060408301518161010086015261305582860182612f49565b915050606083015161012085015260808301516101408501528091505092915050565b6020815260008251604060208401526130946060840182612fd4565b9050602084015160408401528091505092915050565b602081526000611d126020830184612fd4565b634e487b7160e01b600052601160045260246000fd5b6000828210156130e5576130e56130bd565b500390565b634e487b7160e01b600052601260045260246000fd5b60008261310f5761310f6130ea565b500690565b600081600019048311821515161561312e5761312e6130bd565b500290565b600082613142576131426130ea565b500490565b6001600160a01b0381168114612d6357600080fd5b60006020828403121561316e57600080fd5b8135611d1281613147565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156131b2576131b2613179565b60405290565b6040516020810167ffffffffffffffff811182821017156131b2576131b2613179565b60405160a0810167ffffffffffffffff811182821017156131b2576131b2613179565b60405160e0810167ffffffffffffffff811182821017156131b2576131b2613179565b67ffffffffffffffff81168114612d6357600080fd5b600067ffffffffffffffff8084111561325257613252613179565b604051601f8501601f19908116603f0116810190828211818310171561327a5761327a613179565b8160405280935085815286868601111561329357600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126132be57600080fd5b611d1283833560208501613237565b6000606082840312156132df57600080fd5b6132e761318f565b9050813567ffffffffffffffff8082111561330157600080fd5b61330d858386016132ad565b8352602084013591508082111561332357600080fd5b61332f858386016132ad565b6020840152604084013591508082111561334857600080fd5b50613355848285016132ad565b60408301525092915050565b6000818303606081121561337457600080fd5b61337c61318f565b9150823567ffffffffffffffff8082111561339657600080fd5b818501915085601f8301126133aa57600080fd5b6133b986833560208501613237565b84526020601f19840112156133cd57600080fd5b6133d56131b8565b9250602085013591506133e782613221565b818352826020850152604085013592508083111561340457600080fd5b5050613355848285016132cd565b600081360361016081121561342657600080fd5b61342e6131db565b833561343981613147565b815260e0601f198301121561344d57600080fd5b6134556131fe565b9150602084013561346581613221565b8083525060408401356020830152606084013560408301526080840135606083015260a0840135608083015260c084013560a083015260e08401356134a981613221565b60c083015260208101919091526101008301359067ffffffffffffffff8211156134d257600080fd5b6134de36838601613361565b604082015261012084013560608201526101409093013560808401525090919050565b600081356108ed81613221565b60008235605e1983360301811261352457600080fd5b9190910192915050565b6000808335601e1984360301811261354557600080fd5b83018035915067ffffffffffffffff82111561356057600080fd5b60200191503681900382131561292257600080fd5b600181811c9082168061358957607f821691505b602082108114156105c757634e487b7160e01b600052602260045260246000fd5b601f82111561213757600081815260208120601f850160051c810160208610156135d15750805b601f850160051c820191505b818110156135f0578281556001016135dd565b505050505050565b813561360381613221565b815467ffffffffffffffff191667ffffffffffffffff8216178255505050565b67ffffffffffffffff83111561363b5761363b613179565b61364f836136498354613575565b836135aa565b6000601f841160018114613683576000851561366b5750838201355b600019600387901b1c1916600186901b178355610718565b600083815260209020601f19861690835b828110156136b45786850135825560209485019460019092019101613694565b50868210156136d15760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6136ed828361352e565b67ffffffffffffffff81111561370557613705613179565b613719816137138554613575565b856135aa565b6000601f82116001811461374d57600083156137355750838201355b600019600385901b1c1916600184901b1785556137a7565b600085815260209020601f19841690835b8281101561377e578685013582556020948501946001909201910161375e565b508482101561379b5760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506137b8602083018361352e565b6137c6818360018601613623565b50506137d5604083018361352e565b61071a818360028601613623565b6137ed828361352e565b67ffffffffffffffff81111561380557613805613179565b613813816137138554613575565b6000601f821160018114613847576000831561382f5750838201355b600019600385901b1c1916600184901b1785556138a1565b600085815260209020601f19841690835b828110156138785786850135825560209485019460019092019101613858565b50848210156138955760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506138b560208301600183016135f8565b6138ce6138c5604084018461350e565b600283016136e3565b5050565b81356138dd81613147565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff1983541617825550602082013561391281613221565b60018201805467ffffffffffffffff191667ffffffffffffffff83161790555060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c0820135600682015561399661397360e08401613501565b6007830167ffffffffffffffff821667ffffffffffffffff198254161781555050565b6139b06139a761010084018461350e565b600883016137e3565b610120820135600d820155610140820135600e8201555050565b600082198211156139dd576139dd6130bd565b500190565b838152610120810183356139f581613221565b67ffffffffffffffff8082166020850152602086013560408501526040860135606085015260608601356080850152608086013560a085015260a086013560c085015260c08601359150613a4882613221565b1660e08301526101009091019190915292915050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215613aa657600080fd5b81518015158114611d1257600080fd5b634e487b7160e01b600052600160045260246000fd5b600061ffff83811690831681811015613ae757613ae76130bd565b039392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220c7052b64f85cd2f0e60a31f5a231ddafb1d3c1bccb20e5810f9de4d54c42547664736f6c63430008080033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101775760003560e01c80636e2b54ee116100d8578063b396dc791161008c578063f752196b11610066578063f752196b146103fd578063fb1e61ca1461041d578063fc0c546a1461043d57600080fd5b8063b396dc79146103b7578063be5cdc48146103d7578063c0cc4add146103ea57600080fd5b80639777b72c116100bd5780639777b72c14610379578063a29c29a414610381578063a3a0807e1461039457600080fd5b80636e2b54ee146102a157806379502c55146102b457600080fd5b80634641dce61161012f5780636368a471116101145780636368a47114610237578063645116d81461024a5780636b00c8cf1461025d57600080fd5b80634641dce6146101fd5780635da738351461022257600080fd5b806308695fcd1161016057806308695fcd146101c25780630eb6c86f146101d7578063458d2bf1146101ea57600080fd5b806302fa8e651461017c57806305b90773146101a2575b600080fd5b61018f61018a366004612d16565b610464565b6040519081526020015b60405180910390f35b6101b56101b0366004612d16565b6104db565b6040516101999190612d66565b6101d56101d0366004612d79565b6105cd565b005b6101d56101e5366004612d9b565b610720565b61018f6101f8366004612d16565b6108da565b61021061020b366004612d16565b6108f3565b60405160ff9091168152602001610199565b61022a610906565b6040516101999190612dd7565b6101d5610245366004612e5d565b61092d565b6101d5610258366004612eb0565b610c0b565b61028961026b366004612d16565b6000908152601060205260409020600401546001600160a01b031690565b6040516001600160a01b039091168152602001610199565b6101d56102af366004612d16565b610d41565b60408051608081018252600a5460ff80821683526101008204811660208085019190915261ffff6201000084041684860152640100000000909204811660608085019190915284519081018552600b548152600c5492810192909252600d5416928101929092526103229182565b60408051835160ff90811682526020808601518216818401528584015161ffff1683850152606095860151821695830195909552835160808301529383015160a082015291015190911660c082015260e001610199565b61022a6112b2565b6101d561038f366004612d16565b6112d1565b6103a76103a2366004612d16565b611480565b6040519015158152602001610199565b6103ca6103c5366004612d16565b6114b5565b6040516101999190613078565b6101b56103e5366004612d16565b611885565b6103a76103f8366004612d16565b611955565b61018f61040b366004612d16565b60009081526005602052604090205490565b61043061042b366004612d16565b611968565b60405161019991906130aa565b6102897f000000000000000000000000000000000000000000000000000000000000000081565b6000818152600f602052604081206003015481610480846104db565b9050600081600481111561049657610496612d2f565b14806104b3575060018160048111156104b1576104b1612d2f565b145b156104bf575092915050565b6104d3826104ce6001426130d3565b611d01565b949350505050565b6000818152600e602052604081205482906001600160a01b03166105385760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b60448201526064015b60405180910390fd5b6000838152600f6020526040812090815460ff16600481111561055d5761055d612d2f565b14801561057a57506000848152600e60205260409020600d015442115b156105895760029250506105c7565b6001815460ff1660048111156105a1576105a1612d2f565b1480156105b15750806003015442115b156105c05760039250506105c7565b5460ff1691505b50919050565b60016105d883611885565b60048111156105e9576105e9612d2f565b146106365760405162461bcd60e51b815260206004820152601960248201527f536c6f74206e6f7420616363657074696e672070726f6f667300000000000000604482015260640161052f565b6106408282611d19565b600082815260106020908152604080832060018101548452600e909252909120600a5461ffff62010000909104166106848560009081526005602052604090205490565b61068e9190613100565b61071a57600a5460068201546000916064916106b591640100000000900460ff1690613114565b6106bf9190613133565b9050808360030160008282546106d591906130d3565b9091555050600a54600086815260056020526040902054610100820460ff169162010000900461ffff169061070a9190613133565b106107185761071885611f46565b505b50505050565b3361072e602083018361315c565b6001600160a01b0316146107845760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b600061079761079283613412565b6120e5565b6000818152600e60205260409020549091506001600160a01b0316156107ff5760405162461bcd60e51b815260206004820152601660248201527f5265717565737420616c72656164792065786973747300000000000000000000604482015260640161052f565b6000818152600e60205260409020829061081982826138d2565b5061082a90506060830135426139ca565b6000828152600f6020908152604090912060030191909155610858906108529084018461315c565b82612115565b600061086b61086684613412565b61213c565b9050806011600001600082825461088291906139ca565b9091555061089290503382612161565b7f5fdb86c365a247a4d97dcbcc5c3abde9d6e3e2de26273f3fda8eef5073b9a96c82846020018561012001356040516108cd939291906139e2565b60405180910390a1505050565b60006108ed826108e8612273565b61227e565b92915050565b60006108ed82610901612273565b612292565b33600090815260096020526040902060609061092890610925906122f2565b90565b905090565b6000848152600e602052604090205484906001600160a01b03166109855760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000858152600e60205260409020600181015467ffffffffffffffff1685106109f05760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420736c6f740000000000000000000000000000000000000000604482015260640161052f565b604080516020808201899052818301889052825180830384018152606090920190925280519101206000906000818152601060205260408120600181018a905560028101899055919250610a4383611885565b6004811115610a5457610a54612d2f565b14610aa15760405162461bcd60e51b815260206004820152601060248201527f536c6f74206973206e6f74206672656500000000000000000000000000000000604482015260640161052f565b60048084015460008481526003602090815260408083204290559390529190912055610ace828787610c0b565b60048101805473ffffffffffffffffffffffffffffffffffffffff191633179055805460ff1916600190811782556000898152600f6020526040812080830180549193929091610b1f9084906139ca565b90915550506006840154610b333382612161565b8060116000016000828254610b4891906139ca565b9091555050600383018190556004830154610b6c906001600160a01b0316856122ff565b897ff530852268993f91008f1a1e0b09b5c813acd4188481f1fa83c33c7182e814b48a604051610b9e91815260200190565b60405180910390a26001808601549083015467ffffffffffffffff9091161415610bff57815460ff191660011782554260028301556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b80610c585760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642070726f6f6600000000000000000000000000000000000000604482015260640161052f565b600083815260066020526040812090610c6f612273565b815260208101919091526040016000205460ff1615610cd05760405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c7265616479207375626d6974746564000000000000000000604482015260640161052f565b6000838152600660205260408120600191610ce9612273565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f17d5257c85fa8a4b5a4d1f3520e38773826559199467bdce51698fce3d8cae9c8383836040516108cd93929190613a5e565b6000818152600e60205260409020600d8101544211610da25760405162461bcd60e51b815260206004820152601960248201527f52657175657374206e6f74207965742074696d6564206f757400000000000000604482015260640161052f565b80546001600160a01b03163314610dfb5760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e74206164647265737300000000000000000000604482015260640161052f565b6000828152600f6020526040812090815460ff166004811115610e2057610e20612d2f565b14610e6d5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420737461746500000000000000000000000000000000000000604482015260640161052f565b805460ff191660021781558154610e8d906001600160a01b031684612321565b60405183907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a26040805160a0808201835284546001600160a01b03168252825160e081018452600186015467ffffffffffffffff90811682526002870154602083810191909152600388015483870152600488015460608085019190915260058901546080850152600689015494840194909452600788015490911660c0830152830152825190810183526008850180546000946111ea949388939185019290919082908290610f6190613575565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8d90613575565b8015610fda5780601f10610faf57610100808354040283529160200191610fda565b820191906000526020600020905b815481529060010190602001808311610fbd57829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061102390613575565b80601f016020809104026020016040519081016040528092919081815260200182805461104f90613575565b801561109c5780601f106110715761010080835404028352916020019161109c565b820191906000526020600020905b81548152906001019060200180831161107f57829003601f168201915b505050505081526020016001820180546110b590613575565b80601f01602080910402602001604051908101604052809291908181526020018280546110e190613575565b801561112e5780601f106111035761010080835404028352916020019161112e565b820191906000526020600020905b81548152906001019060200180831161111157829003601f168201915b5050505050815260200160028201805461114790613575565b80601f016020809104026020016040519081016040528092919081815260200182805461117390613575565b80156111c05780601f10611195576101008083540402835291602001916111c0565b820191906000526020600020905b8154815290600101906020018083116111a357829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e8201548152505061213c565b9050806011600101600082825461120191906139ca565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561126e57600080fd5b505af1158015611282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a69190613a94565b61071a5761071a613ab6565b33600090815260086020526040902060609061092890610925906122f2565b806000808281526010602052604090205460ff1660048111156112f6576112f6612d2f565b14156113335760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b600082815260106020526040902060048101546001600160a01b0316331461139d5760405162461bcd60e51b815260206004820152601960248201527f536c6f742066696c6c6564206279206f7468657220686f737400000000000000604482015260640161052f565b60006113a884611885565b905060048160048111156113be576113be612d2f565b141561140c5760405162461bcd60e51b815260206004820152600c60248201527f416c726561647920706169640000000000000000000000000000000000000000604482015260640161052f565b600281600481111561142057611420612d2f565b141561143957611434826001015485612343565b61071a565b600381600481111561144d5761144d612d2f565b141561145d576114343385612824565b600181600481111561147157611471612d2f565b141561071a5761071a84611f46565b600080600061149684611491612273565b612846565b90925090508180156104d3575060025460ff9081169116109392505050565b6114bd612c06565b816000808281526010602052604090205460ff1660048111156114e2576114e2612d2f565b141561151f5760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b604482015260640161052f565b6000838152601060205260409020611535612c06565b6001808301546000908152600e6020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186529583015467ffffffffffffffff908116875260028401548786015260038401548787015260048401546060808901919091526005850154608089015260068501549288019290925260078401541660c08701529281019490945282519182018352600881018054919385019291829082906115e590613575565b80601f016020809104026020016040519081016040528092919081815260200182805461161190613575565b801561165e5780601f106116335761010080835404028352916020019161165e565b820191906000526020600020905b81548152906001019060200180831161164157829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff168252830152805160608101825260028401805492909301929091829082906116a790613575565b80601f01602080910402602001604051908101604052809291908181526020018280546116d390613575565b80156117205780601f106116f557610100808354040283529160200191611720565b820191906000526020600020905b81548152906001019060200180831161170357829003601f168201915b5050505050815260200160018201805461173990613575565b80601f016020809104026020016040519081016040528092919081815260200182805461176590613575565b80156117b25780601f10611787576101008083540402835291602001916117b2565b820191906000526020600020905b81548152906001019060200180831161179557829003601f168201915b505050505081526020016002820180546117cb90613575565b80601f01602080910402602001604051908101604052809291908181526020018280546117f790613575565b80156118445780601f1061181957610100808354040283529160200191611844565b820191906000526020600020905b81548152906001019060200180831161182757829003601f168201915b505050919092525050509052508152600d820154602080830191909152600e9092015460409091015290825260029092015491810191909152915050919050565b600081815260106020526040812060018101546118a55750600092915050565b60006118b482600101546104db565b90506004825460ff1660048111156118ce576118ce612d2f565b14156118de575060049392505050565b60028160048111156118f2576118f2612d2f565b1415611902575060029392505050565b600381600481111561191657611916612d2f565b1415611926575060029392505050565b600481600481111561193a5761193a612d2f565b141561194a575060039392505050565b505460ff1692915050565b60006108ed82611963612273565b612929565b611970612c26565b6000828152600e602052604090205482906001600160a01b03166119c85760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000838152600e6020908152604091829020825160a0808201855282546001600160a01b03168252845160e081018652600184015467ffffffffffffffff908116825260028501548287015260038501548288015260048501546060808401919091526005860154608084015260068601549383019390935260078501541660c0820152938201939093528351928301845260088201805491949293928501929182908290611a7690613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611aa290613575565b8015611aef5780601f10611ac457610100808354040283529160200191611aef565b820191906000526020600020905b815481529060010190602001808311611ad257829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff16825283015280516060810182526002840180549290930192909182908290611b3890613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6490613575565b8015611bb15780601f10611b8657610100808354040283529160200191611bb1565b820191906000526020600020905b815481529060010190602001808311611b9457829003601f168201915b50505050508152602001600182018054611bca90613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf690613575565b8015611c435780601f10611c1857610100808354040283529160200191611c43565b820191906000526020600020905b815481529060010190602001808311611c2657829003601f168201915b50505050508152602001600282018054611c5c90613575565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8890613575565b8015611cd55780601f10611caa57610100808354040283529160200191611cd5565b820191906000526020600020905b815481529060010190602001808311611cb857829003601f168201915b505050919092525050509052508152600d8201546020820152600e909101546040909101529392505050565b6000818310611d105781611d12565b825b9392505050565b6000611d248261295c565b9050428110611d755760405162461bcd60e51b815260206004820152601860248201527f506572696f6420686173206e6f7420656e646564207965740000000000000000604482015260640161052f565b600154611d8290826139ca565b4210611dd05760405162461bcd60e51b815260206004820152601460248201527f56616c69646174696f6e2074696d6564206f7574000000000000000000000000604482015260640161052f565b600083815260066020908152604080832085845290915290205460ff1615611e3a5760405162461bcd60e51b815260206004820181905260248201527f50726f6f6620776173207375626d69747465642c206e6f74206d697373696e67604482015260640161052f565b611e448383612929565b611e905760405162461bcd60e51b815260206004820152601660248201527f50726f6f6620776173206e6f7420726571756972656400000000000000000000604482015260640161052f565b600083815260076020908152604080832085845290915290205460ff1615611efa5760405162461bcd60e51b815260206004820152601f60248201527f50726f6f6620616c7265616479206d61726b6564206173206d697373696e6700604482015260640161052f565b60008381526007602090815260408083208584528252808320805460ff1916600190811790915586845260059092528220805491929091611f3c9084906139ca565b9091555050505050565b60008181526010602090815260408083206001810154808552600f90935292206004830154611f7e906001600160a01b031685612824565b6002808401546000868152601060205260408120805460ff19168155600180820183905593810182905560038101829055600401805473ffffffffffffffffffffffffffffffffffffffff191690558383018054929392909190611fe39084906130d3565b909155505060405181815283907f1d31c9f8dea6e179f6a050db117595feea8937029ea51f5168a4780be7e8f5529060200160405180910390a26000858152600560205260408120556000838152600e602052604081206001808501549082015491929161205b919067ffffffffffffffff166130d3565b600783015490915067ffffffffffffffff168111801561209057506001845460ff16600481111561208e5761208e612d2f565b145b156120dc57835460ff191660041784556120ab6001426130d3565b600385015560405185907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a25b50505050505050565b6000816040516020016120f891906130aa565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0382166000908152600860205260409020612137908261296f565b505050565b60006121478261297b565b6020830151516108ed919067ffffffffffffffff16613114565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd90606401602060405180830381600087803b1580156121ef57600080fd5b505af1158015612203573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122279190613a94565b6121375760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015260640161052f565b600061092842612997565b6000611d1261228d8484612292565b6129c3565b6000806122a161010043613100565b905060006122b161010085613100565b905060006122c161010087613100565b90506000610100826122d385876139ca565b6122dd91906139ca565b6122e79190613100565b979650505050505050565b60606000611d1283612a19565b6001600160a01b0382166000908152600960205260409020612137908261296f565b6001600160a01b03821660009081526008602052604090206121379082612a75565b6000828152600e602052604090205482906001600160a01b031661239b5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b604482015260640161052f565b6000838152600f60209081526040808320600e909252909120815460ff1916600317825580546123d4906001600160a01b031686612321565b600084815260106020526040902060048101546123fa906001600160a01b031686612824565b6003808201546000888152600e60209081526040808320815160a0808201845282546001600160a01b03168252835160e081018552600184015467ffffffffffffffff90811682526002850154828801529884015481860152600484015460608083019190915260058501546080830152600685015492820192909252600784015490981660c08901529381019690965281519283018252600881018054949661273d95909492938501929190829082906124b490613575565b80601f01602080910402602001604051908101604052809291908181526020018280546124e090613575565b801561252d5780601f106125025761010080835404028352916020019161252d565b820191906000526020600020905b81548152906001019060200180831161251057829003601f168201915b50505091835250506040805160208181018352600185015467ffffffffffffffff1682528301528051606081018252600284018054929093019290918290829061257690613575565b80601f01602080910402602001604051908101604052809291908181526020018280546125a290613575565b80156125ef5780601f106125c4576101008083540402835291602001916125ef565b820191906000526020600020905b8154815290600101906020018083116125d257829003601f168201915b5050505050815260200160018201805461260890613575565b80601f016020809104026020016040519081016040528092919081815260200182805461263490613575565b80156126815780601f1061265657610100808354040283529160200191612681565b820191906000526020600020905b81548152906001019060200180831161266457829003601f168201915b5050505050815260200160028201805461269a90613575565b80601f01602080910402602001604051908101604052809291908181526020018280546126c690613575565b80156127135780601f106126e857610100808354040283529160200191612713565b820191906000526020600020905b8154815290600101906020018083116126f657829003601f168201915b505050505081525050815250508152602001600d8201548152602001600e8201548152505061297b565b61274791906139ca565b9050806011600101600082825461275e91906139ca565b9091555050815460ff1916600490811783558083015460405163a9059cbb60e01b81526001600160a01b0391821692810192909252602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b1580156127e057600080fd5b505af11580156127f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128189190613a94565b6120dc576120dc613ab6565b6001600160a01b03821660009081526009602052604090206121379082612a75565b600080600061285485611885565b6000868152600360205260408120549192509061287090612997565b9050600182600481111561288657612886612d2f565b14158061289a57506128988582612a81565b155b156128ad57600080935093505050612922565b6128b78686612292565b925060006128c4846129c3565b600254909150600090610100906128de9060ff1682613acc565b60008a8152600460205260409020546128fb9161ffff1690613114565b6129059190613133565b905080158061291b57506129198183613100565b155b9550505050505b9250929050565b60008060006129388585612846565b9092509050818015612953575060025460ff90811690821610155b95945050505050565b60006108ed61296a83612a8b565b612a98565b6000611d128383612ac4565b602081015160808101516040909101516000916108ed91613114565b60006108ed7f000000000000000000000000000000000000000000000000000000000000000083613133565b60008060ff83166129d56001436130d3565b6129df91906130d3565b409050806129ef576129ef613ab6565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b606081600001805480602002602001604051908101604052809291908181526020018280548015612a6957602002820191906000526020600020905b815481526020019060010190808311612a55575b50505050509050919050565b6000611d128383612b13565b6000818311611d12565b60006108ed8260016139ca565b60006108ed7f000000000000000000000000000000000000000000000000000000000000000083613114565b6000818152600183016020526040812054612b0b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108ed565b5060006108ed565b60008181526001830160205260408120548015612bfc576000612b376001836130d3565b8554909150600090612b4b906001906130d3565b9050818114612bb0576000866000018281548110612b6b57612b6b613aef565b9060005260206000200154905080876000018481548110612b8e57612b8e613aef565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612bc157612bc1613b05565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108ed565b60009150506108ed565b6040518060400160405280612c19612c26565b8152602001600081525090565b6040518060a0016040528060006001600160a01b03168152602001612c956040518060e00160405280600067ffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600067ffffffffffffffff1681525090565b8152602001612ca2612cb6565b815260006020820181905260409091015290565b604051806060016040528060608152602001612ce86040518060200160405280600067ffffffffffffffff1681525090565b8152602001612d1160405180606001604052806060815260200160608152602001606081525090565b905290565b600060208284031215612d2857600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60058110612d6357634e487b7160e01b600052602160045260246000fd5b50565b60208101612d7383612d45565b91905290565b60008060408385031215612d8c57600080fd5b50508035926020909101359150565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b82016101608185031215611d1257600080fd5b6020808252825182820181905260009190848201906040850190845b81811015612e0f57835183529284019291840191600101612df3565b50909695505050505050565b60008083601f840112612e2d57600080fd5b50813567ffffffffffffffff811115612e4557600080fd5b60208301915083602082850101111561292257600080fd5b60008060008060608587031215612e7357600080fd5b8435935060208501359250604085013567ffffffffffffffff811115612e9857600080fd5b612ea487828801612e1b565b95989497509550505050565b600080600060408486031215612ec557600080fd5b83359250602084013567ffffffffffffffff811115612ee357600080fd5b612eef86828701612e1b565b9497909650939450505050565b6000815180845260005b81811015612f2257602081850181015186830182015201612f06565b81811115612f34576000602083870101525b50601f01601f19169290920160200192915050565b6000815160608452612f5e6060850182612efc565b905067ffffffffffffffff60208401515116602085015260408301518482036040860152805160608352612f956060840182612efc565b905060208201518382036020850152612fae8282612efc565b915050604082015191508281036040840152612fca8183612efc565b9695505050505050565b60006101606001600160a01b038351168452602083015167ffffffffffffffff808251166020870152602082015160408701526040820151606087015260608201516080870152608082015160a087015260a082015160c08701528060c08301511660e0870152505060408301518161010086015261305582860182612f49565b915050606083015161012085015260808301516101408501528091505092915050565b6020815260008251604060208401526130946060840182612fd4565b9050602084015160408401528091505092915050565b602081526000611d126020830184612fd4565b634e487b7160e01b600052601160045260246000fd5b6000828210156130e5576130e56130bd565b500390565b634e487b7160e01b600052601260045260246000fd5b60008261310f5761310f6130ea565b500690565b600081600019048311821515161561312e5761312e6130bd565b500290565b600082613142576131426130ea565b500490565b6001600160a01b0381168114612d6357600080fd5b60006020828403121561316e57600080fd5b8135611d1281613147565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156131b2576131b2613179565b60405290565b6040516020810167ffffffffffffffff811182821017156131b2576131b2613179565b60405160a0810167ffffffffffffffff811182821017156131b2576131b2613179565b60405160e0810167ffffffffffffffff811182821017156131b2576131b2613179565b67ffffffffffffffff81168114612d6357600080fd5b600067ffffffffffffffff8084111561325257613252613179565b604051601f8501601f19908116603f0116810190828211818310171561327a5761327a613179565b8160405280935085815286868601111561329357600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126132be57600080fd5b611d1283833560208501613237565b6000606082840312156132df57600080fd5b6132e761318f565b9050813567ffffffffffffffff8082111561330157600080fd5b61330d858386016132ad565b8352602084013591508082111561332357600080fd5b61332f858386016132ad565b6020840152604084013591508082111561334857600080fd5b50613355848285016132ad565b60408301525092915050565b6000818303606081121561337457600080fd5b61337c61318f565b9150823567ffffffffffffffff8082111561339657600080fd5b818501915085601f8301126133aa57600080fd5b6133b986833560208501613237565b84526020601f19840112156133cd57600080fd5b6133d56131b8565b9250602085013591506133e782613221565b818352826020850152604085013592508083111561340457600080fd5b5050613355848285016132cd565b600081360361016081121561342657600080fd5b61342e6131db565b833561343981613147565b815260e0601f198301121561344d57600080fd5b6134556131fe565b9150602084013561346581613221565b8083525060408401356020830152606084013560408301526080840135606083015260a0840135608083015260c084013560a083015260e08401356134a981613221565b60c083015260208101919091526101008301359067ffffffffffffffff8211156134d257600080fd5b6134de36838601613361565b604082015261012084013560608201526101409093013560808401525090919050565b600081356108ed81613221565b60008235605e1983360301811261352457600080fd5b9190910192915050565b6000808335601e1984360301811261354557600080fd5b83018035915067ffffffffffffffff82111561356057600080fd5b60200191503681900382131561292257600080fd5b600181811c9082168061358957607f821691505b602082108114156105c757634e487b7160e01b600052602260045260246000fd5b601f82111561213757600081815260208120601f850160051c810160208610156135d15750805b601f850160051c820191505b818110156135f0578281556001016135dd565b505050505050565b813561360381613221565b815467ffffffffffffffff191667ffffffffffffffff8216178255505050565b67ffffffffffffffff83111561363b5761363b613179565b61364f836136498354613575565b836135aa565b6000601f841160018114613683576000851561366b5750838201355b600019600387901b1c1916600186901b178355610718565b600083815260209020601f19861690835b828110156136b45786850135825560209485019460019092019101613694565b50868210156136d15760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6136ed828361352e565b67ffffffffffffffff81111561370557613705613179565b613719816137138554613575565b856135aa565b6000601f82116001811461374d57600083156137355750838201355b600019600385901b1c1916600184901b1785556137a7565b600085815260209020601f19841690835b8281101561377e578685013582556020948501946001909201910161375e565b508482101561379b5760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506137b8602083018361352e565b6137c6818360018601613623565b50506137d5604083018361352e565b61071a818360028601613623565b6137ed828361352e565b67ffffffffffffffff81111561380557613805613179565b613813816137138554613575565b6000601f821160018114613847576000831561382f5750838201355b600019600385901b1c1916600184901b1785556138a1565b600085815260209020601f19841690835b828110156138785786850135825560209485019460019092019101613858565b50848210156138955760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506138b560208301600183016135f8565b6138ce6138c5604084018461350e565b600283016136e3565b5050565b81356138dd81613147565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff1983541617825550602082013561391281613221565b60018201805467ffffffffffffffff191667ffffffffffffffff83161790555060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c0820135600682015561399661397360e08401613501565b6007830167ffffffffffffffff821667ffffffffffffffff198254161781555050565b6139b06139a761010084018461350e565b600883016137e3565b610120820135600d820155610140820135600e8201555050565b600082198211156139dd576139dd6130bd565b500190565b838152610120810183356139f581613221565b67ffffffffffffffff8082166020850152602086013560408501526040860135606085015260608601356080850152608086013560a085015260a086013560c085015260c08601359150613a4882613221565b1660e08301526101009091019190915292915050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215613aa657600080fd5b81518015158114611d1257600080fd5b634e487b7160e01b600052600160045260246000fd5b600061ffff83811690831681811015613ae757613ae76130bd565b039392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea2646970667358221220c7052b64f85cd2f0e60a31f5a231ddafb1d3c1bccb20e5810f9de4d54c42547664736f6c63430008080033", "devdoc": { "kind": "dev", "methods": { @@ -1018,108 +1018,108 @@ "storageLayout": { "storage": [ { - "astId": 3012, + "astId": 3632, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_config", "offset": 0, "slot": "0", - "type": "t_struct(ProofConfig)1582_storage" + "type": "t_struct(ProofConfig)2216_storage" }, { - "astId": 3040, + "astId": 3660, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_slotStarts", "offset": 0, "slot": "3", - "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)" + "type": "t_mapping(t_userDefinedValueType(SlotId)4186,t_uint256)" }, { - "astId": 3045, + "astId": 3665, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_probabilities", "offset": 0, "slot": "4", - "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)" + "type": "t_mapping(t_userDefinedValueType(SlotId)4186,t_uint256)" }, { - "astId": 3050, + "astId": 3670, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_missed", "offset": 0, "slot": "5", - "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)" + "type": "t_mapping(t_userDefinedValueType(SlotId)4186,t_uint256)" }, { - "astId": 3058, + "astId": 3678, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_received", "offset": 0, "slot": "6", - "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_mapping(t_userDefinedValueType(Period)2871,t_bool))" + "type": "t_mapping(t_userDefinedValueType(SlotId)4186,t_mapping(t_userDefinedValueType(Period)3491,t_bool))" }, { - "astId": 3066, + "astId": 3686, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_missing", "offset": 0, "slot": "7", - "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_mapping(t_userDefinedValueType(Period)2871,t_bool))" + "type": "t_mapping(t_userDefinedValueType(SlotId)4186,t_mapping(t_userDefinedValueType(Period)3491,t_bool))" }, { - "astId": 3744, + "astId": 4364, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_requestsPerClient", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1147_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1781_storage)" }, { - "astId": 3749, + "astId": 4369, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_slotsPerHost", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1147_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1781_storage)" }, { - "astId": 1609, + "astId": 2324, "contract": "contracts/Marketplace.sol:Marketplace", "label": "config", "offset": 0, "slot": "10", - "type": "t_struct(MarketplaceConfig)1565_storage" + "type": "t_struct(MarketplaceConfig)2199_storage" }, { - "astId": 1612, - "contract": "contracts/Marketplace.sol:Marketplace", - "label": "_funds", - "offset": 0, - "slot": "14", - "type": "t_struct(MarketplaceFunds)2866_storage" - }, - { - "astId": 1618, + "astId": 2330, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_requests", "offset": 0, - "slot": "18", - "type": "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(Request)3579_storage)" + "slot": "14", + "type": "t_mapping(t_userDefinedValueType(RequestId)4184,t_struct(Request)4199_storage)" }, { - "astId": 1624, + "astId": 2336, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_requestContexts", "offset": 0, - "slot": "19", - "type": "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(RequestContext)1640_storage)" + "slot": "15", + "type": "t_mapping(t_userDefinedValueType(RequestId)4184,t_struct(RequestContext)2355_storage)" }, { - "astId": 1630, + "astId": 2342, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_slots", "offset": 0, - "slot": "20", - "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_struct(Slot)1654_storage)" + "slot": "16", + "type": "t_mapping(t_userDefinedValueType(SlotId)4186,t_struct(Slot)2369_storage)" + }, + { + "astId": 2345, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_marketplaceTotals", + "offset": 0, + "slot": "17", + "type": "t_struct(MarketplaceTotals)3486_storage" } ], "types": { @@ -1149,22 +1149,22 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_enum(RequestState)3619": { + "t_enum(RequestState)4239": { "encoding": "inplace", "label": "enum RequestState", "numberOfBytes": "1" }, - "t_enum(SlotState)3625": { + "t_enum(SlotState)4245": { "encoding": "inplace", "label": "enum SlotState", "numberOfBytes": "1" }, - "t_mapping(t_address,t_struct(Bytes32Set)1147_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1781_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1147_storage" + "value": "t_struct(Bytes32Set)1781_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -1173,44 +1173,44 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_userDefinedValueType(Period)2871,t_bool)": { + "t_mapping(t_userDefinedValueType(Period)3491,t_bool)": { "encoding": "mapping", - "key": "t_userDefinedValueType(Period)2871", + "key": "t_userDefinedValueType(Period)3491", "label": "mapping(Periods.Period => bool)", "numberOfBytes": "32", "value": "t_bool" }, - "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(Request)3579_storage)": { + "t_mapping(t_userDefinedValueType(RequestId)4184,t_struct(Request)4199_storage)": { "encoding": "mapping", - "key": "t_userDefinedValueType(RequestId)3564", + "key": "t_userDefinedValueType(RequestId)4184", "label": "mapping(RequestId => struct Request)", "numberOfBytes": "32", - "value": "t_struct(Request)3579_storage" + "value": "t_struct(Request)4199_storage" }, - "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(RequestContext)1640_storage)": { + "t_mapping(t_userDefinedValueType(RequestId)4184,t_struct(RequestContext)2355_storage)": { "encoding": "mapping", - "key": "t_userDefinedValueType(RequestId)3564", + "key": "t_userDefinedValueType(RequestId)4184", "label": "mapping(RequestId => struct Marketplace.RequestContext)", "numberOfBytes": "32", - "value": "t_struct(RequestContext)1640_storage" + "value": "t_struct(RequestContext)2355_storage" }, - "t_mapping(t_userDefinedValueType(SlotId)3566,t_mapping(t_userDefinedValueType(Period)2871,t_bool))": { + "t_mapping(t_userDefinedValueType(SlotId)4186,t_mapping(t_userDefinedValueType(Period)3491,t_bool))": { "encoding": "mapping", - "key": "t_userDefinedValueType(SlotId)3566", + "key": "t_userDefinedValueType(SlotId)4186", "label": "mapping(SlotId => mapping(Periods.Period => bool))", "numberOfBytes": "32", - "value": "t_mapping(t_userDefinedValueType(Period)2871,t_bool)" + "value": "t_mapping(t_userDefinedValueType(Period)3491,t_bool)" }, - "t_mapping(t_userDefinedValueType(SlotId)3566,t_struct(Slot)1654_storage)": { + "t_mapping(t_userDefinedValueType(SlotId)4186,t_struct(Slot)2369_storage)": { "encoding": "mapping", - "key": "t_userDefinedValueType(SlotId)3566", + "key": "t_userDefinedValueType(SlotId)4186", "label": "mapping(SlotId => struct Marketplace.Slot)", "numberOfBytes": "32", - "value": "t_struct(Slot)1654_storage" + "value": "t_struct(Slot)2369_storage" }, - "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)": { + "t_mapping(t_userDefinedValueType(SlotId)4186,t_uint256)": { "encoding": "mapping", - "key": "t_userDefinedValueType(SlotId)3566", + "key": "t_userDefinedValueType(SlotId)4186", "label": "mapping(SlotId => uint256)", "numberOfBytes": "32", "value": "t_uint256" @@ -1220,12 +1220,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(Ask)3594_storage": { + "t_struct(Ask)4214_storage": { "encoding": "inplace", "label": "struct Ask", "members": [ { - "astId": 3581, + "astId": 4201, "contract": "contracts/Marketplace.sol:Marketplace", "label": "slots", "offset": 0, @@ -1233,7 +1233,7 @@ "type": "t_uint64" }, { - "astId": 3583, + "astId": 4203, "contract": "contracts/Marketplace.sol:Marketplace", "label": "slotSize", "offset": 0, @@ -1241,7 +1241,7 @@ "type": "t_uint256" }, { - "astId": 3585, + "astId": 4205, "contract": "contracts/Marketplace.sol:Marketplace", "label": "duration", "offset": 0, @@ -1249,7 +1249,7 @@ "type": "t_uint256" }, { - "astId": 3587, + "astId": 4207, "contract": "contracts/Marketplace.sol:Marketplace", "label": "proofProbability", "offset": 0, @@ -1257,7 +1257,7 @@ "type": "t_uint256" }, { - "astId": 3589, + "astId": 4209, "contract": "contracts/Marketplace.sol:Marketplace", "label": "reward", "offset": 0, @@ -1265,7 +1265,7 @@ "type": "t_uint256" }, { - "astId": 3591, + "astId": 4211, "contract": "contracts/Marketplace.sol:Marketplace", "label": "collateral", "offset": 0, @@ -1273,7 +1273,7 @@ "type": "t_uint256" }, { - "astId": 3593, + "astId": 4213, "contract": "contracts/Marketplace.sol:Marketplace", "label": "maxSlotLoss", "offset": 0, @@ -1283,27 +1283,27 @@ ], "numberOfBytes": "224" }, - "t_struct(Bytes32Set)1147_storage": { + "t_struct(Bytes32Set)1781_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1146, + "astId": 1780, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)953_storage" + "type": "t_struct(Set)1587_storage" } ], "numberOfBytes": "64" }, - "t_struct(CollateralConfig)1575_storage": { + "t_struct(CollateralConfig)2209_storage": { "encoding": "inplace", "label": "struct CollateralConfig", "members": [ { - "astId": 1568, + "astId": 2202, "contract": "contracts/Marketplace.sol:Marketplace", "label": "repairRewardPercentage", "offset": 0, @@ -1311,7 +1311,7 @@ "type": "t_uint8" }, { - "astId": 1570, + "astId": 2204, "contract": "contracts/Marketplace.sol:Marketplace", "label": "maxNumberOfSlashes", "offset": 1, @@ -1319,7 +1319,7 @@ "type": "t_uint8" }, { - "astId": 1572, + "astId": 2206, "contract": "contracts/Marketplace.sol:Marketplace", "label": "slashCriterion", "offset": 2, @@ -1327,7 +1327,7 @@ "type": "t_uint16" }, { - "astId": 1574, + "astId": 2208, "contract": "contracts/Marketplace.sol:Marketplace", "label": "slashPercentage", "offset": 4, @@ -1337,12 +1337,12 @@ ], "numberOfBytes": "32" }, - "t_struct(Content)3603_storage": { + "t_struct(Content)4223_storage": { "encoding": "inplace", "label": "struct Content", "members": [ { - "astId": 3596, + "astId": 4216, "contract": "contracts/Marketplace.sol:Marketplace", "label": "cid", "offset": 0, @@ -1350,30 +1350,30 @@ "type": "t_string_storage" }, { - "astId": 3599, + "astId": 4219, "contract": "contracts/Marketplace.sol:Marketplace", "label": "erasure", "offset": 0, "slot": "1", - "type": "t_struct(Erasure)3606_storage" + "type": "t_struct(Erasure)4226_storage" }, { - "astId": 3602, + "astId": 4222, "contract": "contracts/Marketplace.sol:Marketplace", "label": "por", "offset": 0, "slot": "2", - "type": "t_struct(PoR)3613_storage" + "type": "t_struct(PoR)4233_storage" } ], "numberOfBytes": "160" }, - "t_struct(Erasure)3606_storage": { + "t_struct(Erasure)4226_storage": { "encoding": "inplace", "label": "struct Erasure", "members": [ { - "astId": 3605, + "astId": 4225, "contract": "contracts/Marketplace.sol:Marketplace", "label": "totalChunks", "offset": 0, @@ -1383,74 +1383,58 @@ ], "numberOfBytes": "32" }, - "t_struct(MarketplaceConfig)1565_storage": { + "t_struct(MarketplaceConfig)2199_storage": { "encoding": "inplace", "label": "struct MarketplaceConfig", "members": [ { - "astId": 1561, + "astId": 2195, "contract": "contracts/Marketplace.sol:Marketplace", "label": "collateral", "offset": 0, "slot": "0", - "type": "t_struct(CollateralConfig)1575_storage" + "type": "t_struct(CollateralConfig)2209_storage" }, { - "astId": 1564, + "astId": 2198, "contract": "contracts/Marketplace.sol:Marketplace", "label": "proofs", "offset": 0, "slot": "1", - "type": "t_struct(ProofConfig)1582_storage" + "type": "t_struct(ProofConfig)2216_storage" } ], "numberOfBytes": "128" }, - "t_struct(MarketplaceFunds)2866_storage": { + "t_struct(MarketplaceTotals)3486_storage": { "encoding": "inplace", - "label": "struct Marketplace.MarketplaceFunds", + "label": "struct Marketplace.MarketplaceTotals", "members": [ { - "astId": 2859, + "astId": 3483, "contract": "contracts/Marketplace.sol:Marketplace", - "label": "balance", + "label": "received", "offset": 0, "slot": "0", "type": "t_uint256" }, { - "astId": 2861, - "contract": "contracts/Marketplace.sol:Marketplace", - "label": "received", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 2863, + "astId": 3485, "contract": "contracts/Marketplace.sol:Marketplace", "label": "sent", "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 2865, - "contract": "contracts/Marketplace.sol:Marketplace", - "label": "slashed", - "offset": 0, - "slot": "3", + "slot": "1", "type": "t_uint256" } ], - "numberOfBytes": "128" + "numberOfBytes": "64" }, - "t_struct(PoR)3613_storage": { + "t_struct(PoR)4233_storage": { "encoding": "inplace", "label": "struct PoR", "members": [ { - "astId": 3608, + "astId": 4228, "contract": "contracts/Marketplace.sol:Marketplace", "label": "u", "offset": 0, @@ -1458,7 +1442,7 @@ "type": "t_bytes_storage" }, { - "astId": 3610, + "astId": 4230, "contract": "contracts/Marketplace.sol:Marketplace", "label": "publicKey", "offset": 0, @@ -1466,7 +1450,7 @@ "type": "t_bytes_storage" }, { - "astId": 3612, + "astId": 4232, "contract": "contracts/Marketplace.sol:Marketplace", "label": "name", "offset": 0, @@ -1476,12 +1460,12 @@ ], "numberOfBytes": "96" }, - "t_struct(ProofConfig)1582_storage": { + "t_struct(ProofConfig)2216_storage": { "encoding": "inplace", "label": "struct ProofConfig", "members": [ { - "astId": 1577, + "astId": 2211, "contract": "contracts/Marketplace.sol:Marketplace", "label": "period", "offset": 0, @@ -1489,7 +1473,7 @@ "type": "t_uint256" }, { - "astId": 1579, + "astId": 2213, "contract": "contracts/Marketplace.sol:Marketplace", "label": "timeout", "offset": 0, @@ -1497,7 +1481,7 @@ "type": "t_uint256" }, { - "astId": 1581, + "astId": 2215, "contract": "contracts/Marketplace.sol:Marketplace", "label": "downtime", "offset": 0, @@ -1507,12 +1491,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Request)3579_storage": { + "t_struct(Request)4199_storage": { "encoding": "inplace", "label": "struct Request", "members": [ { - "astId": 3568, + "astId": 4188, "contract": "contracts/Marketplace.sol:Marketplace", "label": "client", "offset": 0, @@ -1520,23 +1504,23 @@ "type": "t_address" }, { - "astId": 3571, + "astId": 4191, "contract": "contracts/Marketplace.sol:Marketplace", "label": "ask", "offset": 0, "slot": "1", - "type": "t_struct(Ask)3594_storage" + "type": "t_struct(Ask)4214_storage" }, { - "astId": 3574, + "astId": 4194, "contract": "contracts/Marketplace.sol:Marketplace", "label": "content", "offset": 0, "slot": "8", - "type": "t_struct(Content)3603_storage" + "type": "t_struct(Content)4223_storage" }, { - "astId": 3576, + "astId": 4196, "contract": "contracts/Marketplace.sol:Marketplace", "label": "expiry", "offset": 0, @@ -1544,7 +1528,7 @@ "type": "t_uint256" }, { - "astId": 3578, + "astId": 4198, "contract": "contracts/Marketplace.sol:Marketplace", "label": "nonce", "offset": 0, @@ -1554,20 +1538,20 @@ ], "numberOfBytes": "480" }, - "t_struct(RequestContext)1640_storage": { + "t_struct(RequestContext)2355_storage": { "encoding": "inplace", "label": "struct Marketplace.RequestContext", "members": [ { - "astId": 1633, + "astId": 2348, "contract": "contracts/Marketplace.sol:Marketplace", "label": "state", "offset": 0, "slot": "0", - "type": "t_enum(RequestState)3619" + "type": "t_enum(RequestState)4239" }, { - "astId": 1635, + "astId": 2350, "contract": "contracts/Marketplace.sol:Marketplace", "label": "slotsFilled", "offset": 0, @@ -1575,7 +1559,7 @@ "type": "t_uint256" }, { - "astId": 1637, + "astId": 2352, "contract": "contracts/Marketplace.sol:Marketplace", "label": "startedAt", "offset": 0, @@ -1583,7 +1567,7 @@ "type": "t_uint256" }, { - "astId": 1639, + "astId": 2354, "contract": "contracts/Marketplace.sol:Marketplace", "label": "endsAt", "offset": 0, @@ -1593,12 +1577,12 @@ ], "numberOfBytes": "128" }, - "t_struct(Set)953_storage": { + "t_struct(Set)1587_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 948, + "astId": 1582, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_values", "offset": 0, @@ -1606,7 +1590,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 952, + "astId": 1586, "contract": "contracts/Marketplace.sol:Marketplace", "label": "_indexes", "offset": 0, @@ -1616,28 +1600,28 @@ ], "numberOfBytes": "64" }, - "t_struct(Slot)1654_storage": { + "t_struct(Slot)2369_storage": { "encoding": "inplace", "label": "struct Marketplace.Slot", "members": [ { - "astId": 1643, + "astId": 2358, "contract": "contracts/Marketplace.sol:Marketplace", "label": "state", "offset": 0, "slot": "0", - "type": "t_enum(SlotState)3625" + "type": "t_enum(SlotState)4245" }, { - "astId": 1646, + "astId": 2361, "contract": "contracts/Marketplace.sol:Marketplace", "label": "requestId", "offset": 0, "slot": "1", - "type": "t_userDefinedValueType(RequestId)3564" + "type": "t_userDefinedValueType(RequestId)4184" }, { - "astId": 1648, + "astId": 2363, "contract": "contracts/Marketplace.sol:Marketplace", "label": "slotIndex", "offset": 0, @@ -1645,7 +1629,7 @@ "type": "t_uint256" }, { - "astId": 1651, + "astId": 2366, "contract": "contracts/Marketplace.sol:Marketplace", "label": "currentCollateral", "offset": 0, @@ -1653,7 +1637,7 @@ "type": "t_uint256" }, { - "astId": 1653, + "astId": 2368, "contract": "contracts/Marketplace.sol:Marketplace", "label": "host", "offset": 0, @@ -1683,17 +1667,17 @@ "label": "uint8", "numberOfBytes": "1" }, - "t_userDefinedValueType(Period)2871": { + "t_userDefinedValueType(Period)3491": { "encoding": "inplace", "label": "Periods.Period", "numberOfBytes": "32" }, - "t_userDefinedValueType(RequestId)3564": { + "t_userDefinedValueType(RequestId)4184": { "encoding": "inplace", "label": "RequestId", "numberOfBytes": "32" }, - "t_userDefinedValueType(SlotId)3566": { + "t_userDefinedValueType(SlotId)4186": { "encoding": "inplace", "label": "SlotId", "numberOfBytes": "32" diff --git a/deployments/taiko_test/solcInputs/1f43413075cc2b565de996acf5469041.json b/deployments/taiko_test/solcInputs/1f43413075cc2b565de996acf5469041.json new file mode 100644 index 0000000..22f5fde --- /dev/null +++ b/deployments/taiko_test/solcInputs/1f43413075cc2b565de996acf5469041.json @@ -0,0 +1,80 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.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.openzeppelin.com/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 // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\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 unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\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 // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\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/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/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "contracts/Configuration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nstruct MarketplaceConfig {\n CollateralConfig collateral;\n ProofConfig proofs;\n}\n\nstruct CollateralConfig {\n /// @dev percentage of remaining collateral slot after it has been freed\n /// (equivalent to `collateral - (collateral*maxNumberOfSlashes*slashPercentage)/100`)\n /// TODO: to be aligned more closely with actual cost of repair once bandwidth incentives are known,\n /// see https://github.com/codex-storage/codex-contracts-eth/pull/47#issuecomment-1465511949.\n uint8 repairRewardPercentage;\n\n uint8 maxNumberOfSlashes; // frees slot when the number of slashing reaches this value\n uint16 slashCriterion; // amount of proofs missed that lead to slashing\n uint8 slashPercentage; // percentage of the collateral that is slashed\n}\n\nstruct ProofConfig {\n uint256 period; // proofs requirements are calculated per period (in seconds)\n uint256 timeout; // mark proofs as missing before the timeout (in seconds)\n uint8 downtime; // ignore this much recent blocks for proof requirements\n}\n" + }, + "contracts/FuzzMarketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./TestToken.sol\";\nimport \"./Marketplace.sol\";\n\ncontract FuzzMarketplace is Marketplace {\n constructor()\n Marketplace(\n new TestToken(),\n MarketplaceConfig(CollateralConfig(10, 5, 3, 10), ProofConfig(10, 5, 64))\n )\n // solhint-disable-next-line no-empty-blocks\n {\n\n }\n\n // Properties to be tested through fuzzing\n\n MarketplaceTotals private _lastSeenTotals;\n\n function neverDecreaseTotals() public {\n assert(_marketplaceTotals.received >= _lastSeenTotals.received);\n assert(_marketplaceTotals.sent >= _lastSeenTotals.sent);\n _lastSeenTotals = _marketplaceTotals;\n }\n\n function neverLoseFunds() public view {\n uint256 total = _marketplaceTotals.received - _marketplaceTotals.sent;\n assert(token.balanceOf(address(this)) >= total);\n }\n}\n" + }, + "contracts/Marketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport \"./Configuration.sol\";\nimport \"./Requests.sol\";\nimport \"./Proofs.sol\";\nimport \"./StateRetrieval.sol\";\n\ncontract Marketplace is Proofs, StateRetrieval {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n using Requests for Request;\n\n IERC20 public immutable token;\n MarketplaceConfig public config;\n\n mapping(RequestId => Request) private _requests;\n mapping(RequestId => RequestContext) private _requestContexts;\n mapping(SlotId => Slot) internal _slots;\n\n MarketplaceTotals internal _marketplaceTotals;\n\n struct RequestContext {\n RequestState state;\n uint256 slotsFilled;\n uint256 startedAt;\n uint256 endsAt;\n }\n\n struct Slot {\n SlotState state;\n RequestId requestId;\n uint256 slotIndex;\n /// @notice Tracks the current amount of host's collateral that is to be payed out at the end of Slot's lifespan.\n /// @dev When Slot is filled, the collateral is collected in amount of request.ask.collateral\n /// @dev When Host is slashed for missing a proof the slashed amount is reflected in this variable\n uint256 currentCollateral;\n address host;\n }\n\n struct ActiveSlot {\n Request request;\n uint256 slotIndex;\n }\n\n constructor(\n IERC20 token_,\n MarketplaceConfig memory configuration\n ) Proofs(configuration.proofs) {\n token = token_;\n\n require(\n configuration.collateral.repairRewardPercentage <= 100,\n \"Must be less than 100\"\n );\n require(\n configuration.collateral.slashPercentage <= 100,\n \"Must be less than 100\"\n );\n require(\n configuration.collateral.maxNumberOfSlashes *\n configuration.collateral.slashPercentage <=\n 100,\n \"Maximum slashing exceeds 100%\"\n );\n config = configuration;\n }\n\n function requestStorage(Request calldata request) public {\n require(request.client == msg.sender, \"Invalid client address\");\n\n RequestId id = request.id();\n require(_requests[id].client == address(0), \"Request already exists\");\n\n _requests[id] = request;\n _requestContexts[id].endsAt = block.timestamp + request.ask.duration;\n\n _addToMyRequests(request.client, id);\n\n uint256 amount = request.price();\n _marketplaceTotals.received += amount;\n _transferFrom(msg.sender, amount);\n\n emit StorageRequested(id, request.ask, request.expiry);\n }\n\n function fillSlot(\n RequestId requestId,\n uint256 slotIndex,\n bytes calldata proof\n ) public requestIsKnown(requestId) {\n Request storage request = _requests[requestId];\n require(slotIndex < request.ask.slots, \"Invalid slot\");\n\n SlotId slotId = Requests.slotId(requestId, slotIndex);\n Slot storage slot = _slots[slotId];\n slot.requestId = requestId;\n slot.slotIndex = slotIndex;\n\n require(slotState(slotId) == SlotState.Free, \"Slot is not free\");\n\n _startRequiringProofs(slotId, request.ask.proofProbability);\n submitProof(slotId, proof);\n\n slot.host = msg.sender;\n slot.state = SlotState.Filled;\n RequestContext storage context = _requestContexts[requestId];\n context.slotsFilled += 1;\n\n // Collect collateral\n uint256 collateralAmount = request.ask.collateral;\n _transferFrom(msg.sender, collateralAmount);\n _marketplaceTotals.received += collateralAmount;\n slot.currentCollateral = collateralAmount;\n\n _addToMySlots(slot.host, slotId);\n\n emit SlotFilled(requestId, slotIndex);\n if (context.slotsFilled == request.ask.slots) {\n context.state = RequestState.Started;\n context.startedAt = block.timestamp;\n emit RequestFulfilled(requestId);\n }\n }\n\n function freeSlot(SlotId slotId) public slotIsNotFree(slotId) {\n Slot storage slot = _slots[slotId];\n require(slot.host == msg.sender, \"Slot filled by other host\");\n SlotState state = slotState(slotId);\n require(state != SlotState.Paid, \"Already paid\");\n\n if (state == SlotState.Finished) {\n _payoutSlot(slot.requestId, slotId);\n } else if (state == SlotState.Failed) {\n _removeFromMySlots(msg.sender, slotId);\n } else if (state == SlotState.Filled) {\n _forciblyFreeSlot(slotId);\n }\n }\n\n function markProofAsMissing(SlotId slotId, Period period) public {\n require(slotState(slotId) == SlotState.Filled, \"Slot not accepting proofs\");\n _markProofAsMissing(slotId, period);\n Slot storage slot = _slots[slotId];\n Request storage request = _requests[slot.requestId];\n\n if (missingProofs(slotId) % config.collateral.slashCriterion == 0) {\n uint256 slashedAmount = (request.ask.collateral *\n config.collateral.slashPercentage) / 100;\n slot.currentCollateral -= slashedAmount;\n if (\n missingProofs(slotId) / config.collateral.slashCriterion >=\n config.collateral.maxNumberOfSlashes\n ) {\n // When the number of slashings is at or above the allowed amount,\n // free the slot.\n _forciblyFreeSlot(slotId);\n }\n }\n }\n\n function _forciblyFreeSlot(SlotId slotId) internal {\n Slot storage slot = _slots[slotId];\n RequestId requestId = slot.requestId;\n RequestContext storage context = _requestContexts[requestId];\n\n _removeFromMySlots(slot.host, slotId);\n\n uint256 slotIndex = slot.slotIndex;\n delete _slots[slotId];\n context.slotsFilled -= 1;\n emit SlotFreed(requestId, slotIndex);\n _resetMissingProofs(slotId);\n\n Request storage request = _requests[requestId];\n uint256 slotsLost = request.ask.slots - context.slotsFilled;\n if (\n slotsLost > request.ask.maxSlotLoss &&\n context.state == RequestState.Started\n ) {\n context.state = RequestState.Failed;\n context.endsAt = block.timestamp - 1;\n emit RequestFailed(requestId);\n\n // TODO: send client remaining funds\n }\n }\n\n function _payoutSlot(\n RequestId requestId,\n SlotId slotId\n ) private requestIsKnown(requestId) {\n RequestContext storage context = _requestContexts[requestId];\n Request storage request = _requests[requestId];\n context.state = RequestState.Finished;\n _removeFromMyRequests(request.client, requestId);\n Slot storage slot = _slots[slotId];\n\n _removeFromMySlots(slot.host, slotId);\n\n uint256 amount = _requests[requestId].pricePerSlot() +\n slot.currentCollateral;\n _marketplaceTotals.sent += amount;\n slot.state = SlotState.Paid;\n assert(token.transfer(slot.host, amount));\n }\n\n /// @notice Withdraws storage request funds back to the client that deposited them.\n /// @dev Request must be expired, must be in RequestState.New, and the transaction must originate from the depositer address.\n /// @param requestId the id of the request\n function withdrawFunds(RequestId requestId) public {\n Request storage request = _requests[requestId];\n require(block.timestamp > request.expiry, \"Request not yet timed out\");\n require(request.client == msg.sender, \"Invalid client address\");\n RequestContext storage context = _requestContexts[requestId];\n require(context.state == RequestState.New, \"Invalid state\");\n\n // Update request state to Cancelled. Handle in the withdraw transaction\n // as there needs to be someone to pay for the gas to update the state\n context.state = RequestState.Cancelled;\n _removeFromMyRequests(request.client, requestId);\n\n emit RequestCancelled(requestId);\n\n // TODO: To be changed once we start paying out hosts for the time they\n // fill a slot. The amount that we paid to hosts will then have to be\n // deducted from the price.\n uint256 amount = request.price();\n _marketplaceTotals.sent += amount;\n assert(token.transfer(msg.sender, amount));\n }\n\n function getActiveSlot(\n SlotId slotId\n ) public view slotIsNotFree(slotId) returns (ActiveSlot memory) {\n Slot storage slot = _slots[slotId];\n ActiveSlot memory activeSlot;\n activeSlot.request = _requests[slot.requestId];\n activeSlot.slotIndex = slot.slotIndex;\n return activeSlot;\n }\n\n modifier requestIsKnown(RequestId requestId) {\n require(_requests[requestId].client != address(0), \"Unknown request\");\n _;\n }\n\n function getRequest(\n RequestId requestId\n ) public view requestIsKnown(requestId) returns (Request memory) {\n return _requests[requestId];\n }\n\n modifier slotIsNotFree(SlotId slotId) {\n require(_slots[slotId].state != SlotState.Free, \"Slot is free\");\n _;\n }\n\n function requestEnd(RequestId requestId) public view returns (uint256) {\n uint256 end = _requestContexts[requestId].endsAt;\n RequestState state = requestState(requestId);\n if (state == RequestState.New || state == RequestState.Started) {\n return end;\n } else {\n return Math.min(end, block.timestamp - 1);\n }\n }\n\n function getHost(SlotId slotId) public view returns (address) {\n return _slots[slotId].host;\n }\n\n function requestState(\n RequestId requestId\n ) public view requestIsKnown(requestId) returns (RequestState) {\n RequestContext storage context = _requestContexts[requestId];\n if (\n context.state == RequestState.New &&\n block.timestamp > _requests[requestId].expiry\n ) {\n return RequestState.Cancelled;\n } else if (\n context.state == RequestState.Started && block.timestamp > context.endsAt\n ) {\n return RequestState.Finished;\n } else {\n return context.state;\n }\n }\n\n function slotState(SlotId slotId) public view override returns (SlotState) {\n Slot storage slot = _slots[slotId];\n if (RequestId.unwrap(slot.requestId) == 0) {\n return SlotState.Free;\n }\n RequestState reqState = requestState(slot.requestId);\n if (slot.state == SlotState.Paid) {\n return SlotState.Paid;\n }\n if (reqState == RequestState.Cancelled) {\n return SlotState.Finished;\n }\n if (reqState == RequestState.Finished) {\n return SlotState.Finished;\n }\n if (reqState == RequestState.Failed) {\n return SlotState.Failed;\n }\n return slot.state;\n }\n\n function _transferFrom(address sender, uint256 amount) internal {\n address receiver = address(this);\n require(token.transferFrom(sender, receiver, amount), \"Transfer failed\");\n }\n\n event StorageRequested(RequestId requestId, Ask ask, uint256 expiry);\n event RequestFulfilled(RequestId indexed requestId);\n event RequestFailed(RequestId indexed requestId);\n event SlotFilled(\n RequestId indexed requestId,\n uint256 slotIndex\n );\n event SlotFreed(\n RequestId indexed requestId,\n uint256 slotIndex\n );\n event RequestCancelled(RequestId indexed requestId);\n\n struct MarketplaceTotals {\n uint256 received;\n uint256 sent;\n }\n}\n" + }, + "contracts/Periods.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\ncontract Periods {\n type Period is uint256;\n\n uint256 internal immutable _secondsPerPeriod;\n\n constructor(uint256 secondsPerPeriod) {\n _secondsPerPeriod = secondsPerPeriod;\n }\n\n function _periodOf(uint256 timestamp) internal view returns (Period) {\n return Period.wrap(timestamp / _secondsPerPeriod);\n }\n\n function _blockPeriod() internal view returns (Period) {\n return _periodOf(block.timestamp);\n }\n\n function _nextPeriod(Period period) internal pure returns (Period) {\n return Period.wrap(Period.unwrap(period) + 1);\n }\n\n function _periodStart(Period period) internal view returns (uint256) {\n return Period.unwrap(period) * _secondsPerPeriod;\n }\n\n function _periodEnd(Period period) internal view returns (uint256) {\n return _periodStart(_nextPeriod(period));\n }\n\n function _isBefore(Period a, Period b) internal pure returns (bool) {\n return Period.unwrap(a) < Period.unwrap(b);\n }\n\n function _isAfter(Period a, Period b) internal pure returns (bool) {\n return _isBefore(b, a);\n }\n}\n" + }, + "contracts/Proofs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport \"./Configuration.sol\";\nimport \"./Requests.sol\";\nimport \"./Periods.sol\";\n\nabstract contract Proofs is Periods {\n ProofConfig private _config;\n\n constructor(ProofConfig memory config) Periods(config.period) {\n require(block.number > 256, \"Insufficient block height\");\n _config = config;\n }\n\n mapping(SlotId => uint256) private _slotStarts;\n mapping(SlotId => uint256) private _probabilities;\n mapping(SlotId => uint256) private _missed;\n mapping(SlotId => mapping(Period => bool)) private _received;\n mapping(SlotId => mapping(Period => bool)) private _missing;\n\n function slotState(SlotId id) public view virtual returns (SlotState);\n\n function missingProofs(SlotId slotId) public view returns (uint256) {\n return _missed[slotId];\n }\n\n function _resetMissingProofs(SlotId slotId) internal {\n _missed[slotId] = 0;\n }\n\n function _startRequiringProofs(SlotId id, uint256 probability) internal {\n _slotStarts[id] = block.timestamp;\n _probabilities[id] = probability;\n }\n\n function _getPointer(SlotId id, Period period) internal view returns (uint8) {\n uint256 blockNumber = block.number % 256;\n uint256 periodNumber = Period.unwrap(period) % 256;\n uint256 idOffset = uint256(SlotId.unwrap(id)) % 256;\n uint256 pointer = (blockNumber + periodNumber + idOffset) % 256;\n return uint8(pointer);\n }\n\n function getPointer(SlotId id) public view returns (uint8) {\n return _getPointer(id, _blockPeriod());\n }\n\n function _getChallenge(uint8 pointer) internal view returns (bytes32) {\n bytes32 hash = blockhash(block.number - 1 - pointer);\n assert(uint256(hash) != 0);\n return keccak256(abi.encode(hash));\n }\n\n function _getChallenge(\n SlotId id,\n Period period\n ) internal view returns (bytes32) {\n return _getChallenge(_getPointer(id, period));\n }\n\n function getChallenge(SlotId id) public view returns (bytes32) {\n return _getChallenge(id, _blockPeriod());\n }\n\n function _getProofRequirement(\n SlotId id,\n Period period\n ) internal view returns (bool isRequired, uint8 pointer) {\n SlotState state = slotState(id);\n Period start = _periodOf(_slotStarts[id]);\n if (state != SlotState.Filled || !_isAfter(period, start)) {\n return (false, 0);\n }\n pointer = _getPointer(id, period);\n bytes32 challenge = _getChallenge(pointer);\n uint256 probability = (_probabilities[id] * (256 - _config.downtime)) / 256;\n isRequired = probability == 0 || uint256(challenge) % probability == 0;\n }\n\n function _isProofRequired(\n SlotId id,\n Period period\n ) internal view returns (bool) {\n bool isRequired;\n uint8 pointer;\n (isRequired, pointer) = _getProofRequirement(id, period);\n return isRequired && pointer >= _config.downtime;\n }\n\n function isProofRequired(SlotId id) public view returns (bool) {\n return _isProofRequired(id, _blockPeriod());\n }\n\n function willProofBeRequired(SlotId id) public view returns (bool) {\n bool isRequired;\n uint8 pointer;\n (isRequired, pointer) = _getProofRequirement(id, _blockPeriod());\n return isRequired && pointer < _config.downtime;\n }\n\n function submitProof(SlotId id, bytes calldata proof) public {\n require(proof.length > 0, \"Invalid proof\"); // TODO: replace by actual check\n require(!_received[id][_blockPeriod()], \"Proof already submitted\");\n _received[id][_blockPeriod()] = true;\n emit ProofSubmitted(id, proof);\n }\n\n function _markProofAsMissing(SlotId id, Period missedPeriod) internal {\n uint256 end = _periodEnd(missedPeriod);\n require(end < block.timestamp, \"Period has not ended yet\");\n require(block.timestamp < end + _config.timeout, \"Validation timed out\");\n require(!_received[id][missedPeriod], \"Proof was submitted, not missing\");\n require(_isProofRequired(id, missedPeriod), \"Proof was not required\");\n require(!_missing[id][missedPeriod], \"Proof already marked as missing\");\n _missing[id][missedPeriod] = true;\n _missed[id] += 1;\n }\n\n event ProofSubmitted(SlotId id, bytes proof);\n}\n" + }, + "contracts/Requests.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\ntype RequestId is bytes32;\ntype SlotId is bytes32;\n\nstruct Request {\n address client;\n Ask ask;\n Content content;\n uint256 expiry; // timestamp as seconds since unix epoch at which this request expires\n bytes32 nonce; // random nonce to differentiate between similar requests\n}\n\nstruct Ask {\n uint64 slots; // the number of requested slots\n uint256 slotSize; // amount of storage per slot (in number of bytes)\n uint256 duration; // how long content should be stored (in seconds)\n uint256 proofProbability; // how often storage proofs are required\n uint256 reward; // amount of tokens paid per second per slot to hosts\n uint256 collateral; // amount of tokens required to be deposited by the hosts in order to fill the slot\n uint64 maxSlotLoss; // Max slots that can be lost without data considered to be lost\n}\n\nstruct Content {\n string cid; // content id (if part of a larger set, the chunk cid)\n Erasure erasure; // Erasure coding attributes\n PoR por; // Proof of Retrievability parameters\n}\n\nstruct Erasure {\n uint64 totalChunks; // the total number of chunks in the larger data set\n}\n\nstruct PoR {\n bytes u; // parameters u_1..u_s\n bytes publicKey; // public key\n bytes name; // random name\n}\n\nenum RequestState {\n New, // [default] waiting to fill slots\n Started, // all slots filled, accepting regular proofs\n Cancelled, // not enough slots filled before expiry\n Finished, // successfully completed\n Failed // too many nodes have failed to provide proofs, data lost\n}\n\nenum SlotState {\n Free, // [default] not filled yet, or host has vacated the slot\n Filled, // host has filled slot\n Finished, // successfully completed\n Failed, // the request has failed\n Paid // host has been paid\n}\n\nlibrary Requests {\n function id(Request memory request) internal pure returns (RequestId) {\n return RequestId.wrap(keccak256(abi.encode(request)));\n }\n\n function slotId(\n RequestId requestId,\n uint256 slotIndex\n ) internal pure returns (SlotId) {\n return SlotId.wrap(keccak256(abi.encode(requestId, slotIndex)));\n }\n\n function toRequestIds(\n bytes32[] memory ids\n ) internal pure returns (RequestId[] memory result) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := ids\n }\n }\n\n function toSlotIds(\n bytes32[] memory ids\n ) internal pure returns (SlotId[] memory result) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := ids\n }\n }\n\n function pricePerSlot(\n Request memory request\n ) internal pure returns (uint256) {\n return request.ask.duration * request.ask.reward;\n }\n\n function price(Request memory request) internal pure returns (uint256) {\n return request.ask.slots * pricePerSlot(request);\n }\n}\n" + }, + "contracts/StateRetrieval.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport \"./Requests.sol\";\n\ncontract StateRetrieval {\n using EnumerableSet for EnumerableSet.Bytes32Set;\n using Requests for bytes32[];\n\n mapping(address => EnumerableSet.Bytes32Set) private _requestsPerClient;\n mapping(address => EnumerableSet.Bytes32Set) private _slotsPerHost;\n\n function myRequests() public view returns (RequestId[] memory) {\n return _requestsPerClient[msg.sender].values().toRequestIds();\n }\n\n function mySlots() public view returns (SlotId[] memory) {\n return _slotsPerHost[msg.sender].values().toSlotIds();\n }\n\n function _hasSlots(address host) internal view returns (bool) {\n return _slotsPerHost[host].length() > 0;\n }\n\n function _addToMyRequests(address client, RequestId requestId) internal {\n _requestsPerClient[client].add(RequestId.unwrap(requestId));\n }\n\n function _addToMySlots(address host, SlotId slotId) internal {\n _slotsPerHost[host].add(SlotId.unwrap(slotId));\n }\n\n function _removeFromMyRequests(address client, RequestId requestId) internal {\n _requestsPerClient[client].remove(RequestId.unwrap(requestId));\n }\n\n function _removeFromMySlots(address host, SlotId slotId) internal {\n _slotsPerHost[host].remove(SlotId.unwrap(slotId));\n }\n}\n" + }, + "contracts/TestMarketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./Marketplace.sol\";\n\n// exposes internal functions of Marketplace for testing\ncontract TestMarketplace is Marketplace {\n constructor(\n IERC20 token,\n MarketplaceConfig memory config\n )\n Marketplace(token, config) // solhint-disable-next-line no-empty-blocks\n {}\n\n function forciblyFreeSlot(SlotId slotId) public {\n _forciblyFreeSlot(slotId);\n }\n\n function getSlotCollateral(SlotId slotId) public view returns (uint256) {\n return _slots[slotId].currentCollateral;\n }\n}\n" + }, + "contracts/TestProofs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./Proofs.sol\";\n\n// exposes internal functions of Proofs for testing\ncontract TestProofs is Proofs {\n mapping(SlotId => SlotState) private _states;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(ProofConfig memory config) Proofs(config) {}\n\n function slotState(SlotId slotId) public view override returns (SlotState) {\n return _states[slotId];\n }\n\n function startRequiringProofs(SlotId slot, uint256 probability) public {\n _startRequiringProofs(slot, probability);\n }\n\n function markProofAsMissing(SlotId id, Period period) public {\n _markProofAsMissing(id, period);\n }\n\n function setSlotState(SlotId id, SlotState state) public {\n _states[id] = state;\n }\n}\n" + }, + "contracts/TestToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n // solhint-disable-next-line no-empty-blocks\n constructor() ERC20(\"TestToken\", \"TST\") {}\n\n function mint(address holder, uint256 amount) public {\n _mint(holder, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file