From ffcc0e5ee6099f6540d4b41429d21bad8f74b691 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 19 Jun 2023 14:11:09 +0200 Subject: [PATCH] Deployed on taiko test net --- deployments/taiko_test/.chainId | 1 + deployments/taiko_test/Marketplace.json | 1703 +++++++++++++++++ deployments/taiko_test/TestToken.json | 439 +++++ .../9671d4e1820229dcd69b349a99feb65b.json | 65 + .../e700509efb579c8cd23fdb7d2aca156d.json | 80 + 5 files changed, 2288 insertions(+) create mode 100644 deployments/taiko_test/.chainId create mode 100644 deployments/taiko_test/Marketplace.json create mode 100644 deployments/taiko_test/TestToken.json create mode 100644 deployments/taiko_test/solcInputs/9671d4e1820229dcd69b349a99feb65b.json create mode 100644 deployments/taiko_test/solcInputs/e700509efb579c8cd23fdb7d2aca156d.json diff --git a/deployments/taiko_test/.chainId b/deployments/taiko_test/.chainId new file mode 100644 index 0000000..d455637 --- /dev/null +++ b/deployments/taiko_test/.chainId @@ -0,0 +1 @@ +167005 \ No newline at end of file diff --git a/deployments/taiko_test/Marketplace.json b/deployments/taiko_test/Marketplace.json new file mode 100644 index 0000000..9f88468 --- /dev/null +++ b/deployments/taiko_test/Marketplace.json @@ -0,0 +1,1703 @@ +{ + "address": "0xDB2a8A1c8Df776F1C544a56a7734a865ad1C05e8", + "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" + } + ], + "transactionHash": "0x50307964c50857e9563ae3cc7922e34770763a2eb79c5defc9d396de7c5384e0", + "receipt": { + "to": null, + "from": "0xD40C3aED27Cb03CC671b66Fd52d81AE9d8702BE4", + "contractAddress": "0xDB2a8A1c8Df776F1C544a56a7734a865ad1C05e8", + "transactionIndex": 6, + "gasUsed": "3673077", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x153ceefffd4c38d0400a8f0e3e80c81e4b4a6bac2731134a60d8fedfe46de85b", + "transactionHash": "0x50307964c50857e9563ae3cc7922e34770763a2eb79c5defc9d396de7c5384e0", + "logs": [], + "blockNumber": 262545, + "cumulativeGasUsed": "5545143", + "status": 1, + "byzantium": true + }, + "args": [ + "0x95658FdA29e3b547107c95c11dD5e4a1A034C4AB", + { + "collateral": { + "repairRewardPercentage": 10, + "maxNumberOfSlashes": 5, + "slashCriterion": 3, + "slashPercentage": 10 + }, + "proofs": { + "period": 10, + "timeout": 5, + "downtime": 64 + } + } + ], + "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", + "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 + }, + "storageLayout": { + "storage": [ + { + "astId": 3012, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_config", + "offset": 0, + "slot": "0", + "type": "t_struct(ProofConfig)1582_storage" + }, + { + "astId": 3040, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_slotStarts", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)" + }, + { + "astId": 3045, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_probabilities", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)" + }, + { + "astId": 3050, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_missed", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)" + }, + { + "astId": 3058, + "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))" + }, + { + "astId": 3066, + "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))" + }, + { + "astId": 3744, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_requestsPerClient", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_address,t_struct(Bytes32Set)1147_storage)" + }, + { + "astId": 3749, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_slotsPerHost", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_address,t_struct(Bytes32Set)1147_storage)" + }, + { + "astId": 1609, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "config", + "offset": 0, + "slot": "10", + "type": "t_struct(MarketplaceConfig)1565_storage" + }, + { + "astId": 1612, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_funds", + "offset": 0, + "slot": "14", + "type": "t_struct(MarketplaceFunds)2866_storage" + }, + { + "astId": 1618, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_requests", + "offset": 0, + "slot": "18", + "type": "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(Request)3579_storage)" + }, + { + "astId": 1624, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_requestContexts", + "offset": 0, + "slot": "19", + "type": "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(RequestContext)1640_storage)" + }, + { + "astId": 1630, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_slots", + "offset": 0, + "slot": "20", + "type": "t_mapping(t_userDefinedValueType(SlotId)3566,t_struct(Slot)1654_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_bytes_storage": { + "encoding": "bytes", + "label": "bytes", + "numberOfBytes": "32" + }, + "t_enum(RequestState)3619": { + "encoding": "inplace", + "label": "enum RequestState", + "numberOfBytes": "1" + }, + "t_enum(SlotState)3625": { + "encoding": "inplace", + "label": "enum SlotState", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_struct(Bytes32Set)1147_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.Bytes32Set)", + "numberOfBytes": "32", + "value": "t_struct(Bytes32Set)1147_storage" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_userDefinedValueType(Period)2871,t_bool)": { + "encoding": "mapping", + "key": "t_userDefinedValueType(Period)2871", + "label": "mapping(Periods.Period => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(Request)3579_storage)": { + "encoding": "mapping", + "key": "t_userDefinedValueType(RequestId)3564", + "label": "mapping(RequestId => struct Request)", + "numberOfBytes": "32", + "value": "t_struct(Request)3579_storage" + }, + "t_mapping(t_userDefinedValueType(RequestId)3564,t_struct(RequestContext)1640_storage)": { + "encoding": "mapping", + "key": "t_userDefinedValueType(RequestId)3564", + "label": "mapping(RequestId => struct Marketplace.RequestContext)", + "numberOfBytes": "32", + "value": "t_struct(RequestContext)1640_storage" + }, + "t_mapping(t_userDefinedValueType(SlotId)3566,t_mapping(t_userDefinedValueType(Period)2871,t_bool))": { + "encoding": "mapping", + "key": "t_userDefinedValueType(SlotId)3566", + "label": "mapping(SlotId => mapping(Periods.Period => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_userDefinedValueType(Period)2871,t_bool)" + }, + "t_mapping(t_userDefinedValueType(SlotId)3566,t_struct(Slot)1654_storage)": { + "encoding": "mapping", + "key": "t_userDefinedValueType(SlotId)3566", + "label": "mapping(SlotId => struct Marketplace.Slot)", + "numberOfBytes": "32", + "value": "t_struct(Slot)1654_storage" + }, + "t_mapping(t_userDefinedValueType(SlotId)3566,t_uint256)": { + "encoding": "mapping", + "key": "t_userDefinedValueType(SlotId)3566", + "label": "mapping(SlotId => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Ask)3594_storage": { + "encoding": "inplace", + "label": "struct Ask", + "members": [ + { + "astId": 3581, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "slots", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 3583, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "slotSize", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 3585, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "duration", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3587, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "proofProbability", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 3589, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "reward", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 3591, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "collateral", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 3593, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "maxSlotLoss", + "offset": 0, + "slot": "6", + "type": "t_uint64" + } + ], + "numberOfBytes": "224" + }, + "t_struct(Bytes32Set)1147_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Bytes32Set", + "members": [ + { + "astId": 1146, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)953_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(CollateralConfig)1575_storage": { + "encoding": "inplace", + "label": "struct CollateralConfig", + "members": [ + { + "astId": 1568, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "repairRewardPercentage", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 1570, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "maxNumberOfSlashes", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 1572, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "slashCriterion", + "offset": 2, + "slot": "0", + "type": "t_uint16" + }, + { + "astId": 1574, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "slashPercentage", + "offset": 4, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Content)3603_storage": { + "encoding": "inplace", + "label": "struct Content", + "members": [ + { + "astId": 3596, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "cid", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 3599, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "erasure", + "offset": 0, + "slot": "1", + "type": "t_struct(Erasure)3606_storage" + }, + { + "astId": 3602, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "por", + "offset": 0, + "slot": "2", + "type": "t_struct(PoR)3613_storage" + } + ], + "numberOfBytes": "160" + }, + "t_struct(Erasure)3606_storage": { + "encoding": "inplace", + "label": "struct Erasure", + "members": [ + { + "astId": 3605, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "totalChunks", + "offset": 0, + "slot": "0", + "type": "t_uint64" + } + ], + "numberOfBytes": "32" + }, + "t_struct(MarketplaceConfig)1565_storage": { + "encoding": "inplace", + "label": "struct MarketplaceConfig", + "members": [ + { + "astId": 1561, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "collateral", + "offset": 0, + "slot": "0", + "type": "t_struct(CollateralConfig)1575_storage" + }, + { + "astId": 1564, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "proofs", + "offset": 0, + "slot": "1", + "type": "t_struct(ProofConfig)1582_storage" + } + ], + "numberOfBytes": "128" + }, + "t_struct(MarketplaceFunds)2866_storage": { + "encoding": "inplace", + "label": "struct Marketplace.MarketplaceFunds", + "members": [ + { + "astId": 2859, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "balance", + "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, + "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", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_struct(PoR)3613_storage": { + "encoding": "inplace", + "label": "struct PoR", + "members": [ + { + "astId": 3608, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "u", + "offset": 0, + "slot": "0", + "type": "t_bytes_storage" + }, + { + "astId": 3610, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "publicKey", + "offset": 0, + "slot": "1", + "type": "t_bytes_storage" + }, + { + "astId": 3612, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "name", + "offset": 0, + "slot": "2", + "type": "t_bytes_storage" + } + ], + "numberOfBytes": "96" + }, + "t_struct(ProofConfig)1582_storage": { + "encoding": "inplace", + "label": "struct ProofConfig", + "members": [ + { + "astId": 1577, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "period", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1579, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "timeout", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 1581, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "downtime", + "offset": 0, + "slot": "2", + "type": "t_uint8" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Request)3579_storage": { + "encoding": "inplace", + "label": "struct Request", + "members": [ + { + "astId": 3568, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "client", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3571, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "ask", + "offset": 0, + "slot": "1", + "type": "t_struct(Ask)3594_storage" + }, + { + "astId": 3574, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "content", + "offset": 0, + "slot": "8", + "type": "t_struct(Content)3603_storage" + }, + { + "astId": 3576, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "expiry", + "offset": 0, + "slot": "13", + "type": "t_uint256" + }, + { + "astId": 3578, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "nonce", + "offset": 0, + "slot": "14", + "type": "t_bytes32" + } + ], + "numberOfBytes": "480" + }, + "t_struct(RequestContext)1640_storage": { + "encoding": "inplace", + "label": "struct Marketplace.RequestContext", + "members": [ + { + "astId": 1633, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "state", + "offset": 0, + "slot": "0", + "type": "t_enum(RequestState)3619" + }, + { + "astId": 1635, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "slotsFilled", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 1637, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "startedAt", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1639, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "endsAt", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_struct(Set)953_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 948, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 952, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Slot)1654_storage": { + "encoding": "inplace", + "label": "struct Marketplace.Slot", + "members": [ + { + "astId": 1643, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "state", + "offset": 0, + "slot": "0", + "type": "t_enum(SlotState)3625" + }, + { + "astId": 1646, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "requestId", + "offset": 0, + "slot": "1", + "type": "t_userDefinedValueType(RequestId)3564" + }, + { + "astId": 1648, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "slotIndex", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1651, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "currentCollateral", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 1653, + "contract": "contracts/Marketplace.sol:Marketplace", + "label": "host", + "offset": 0, + "slot": "4", + "type": "t_address" + } + ], + "numberOfBytes": "160" + }, + "t_uint16": { + "encoding": "inplace", + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + }, + "t_userDefinedValueType(Period)2871": { + "encoding": "inplace", + "label": "Periods.Period", + "numberOfBytes": "32" + }, + "t_userDefinedValueType(RequestId)3564": { + "encoding": "inplace", + "label": "RequestId", + "numberOfBytes": "32" + }, + "t_userDefinedValueType(SlotId)3566": { + "encoding": "inplace", + "label": "SlotId", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/taiko_test/TestToken.json b/deployments/taiko_test/TestToken.json new file mode 100644 index 0000000..1b85a54 --- /dev/null +++ b/deployments/taiko_test/TestToken.json @@ -0,0 +1,439 @@ +{ + "address": "0x95658FdA29e3b547107c95c11dD5e4a1A034C4AB", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x727bfd3b536568b1cf787ce73f8d3273bde11f847762a77633ae46ecf83e5877", + "receipt": { + "to": null, + "from": "0xD40C3aED27Cb03CC671b66Fd52d81AE9d8702BE4", + "contractAddress": "0x95658FdA29e3b547107c95c11dD5e4a1A034C4AB", + "transactionIndex": 4, + "gasUsed": "669687", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xb7b706e67bbb83fa9973f7eb773f89fc22c9a4ea56a4aad6ca5a782a035d6bb8", + "transactionHash": "0x727bfd3b536568b1cf787ce73f8d3273bde11f847762a77633ae46ecf83e5877", + "logs": [], + "blockNumber": 187454, + "cumulativeGasUsed": "1936262", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "e700509efb579c8cd23fdb7d2aca156d", + "metadata": "{\"compiler\":{\"version\":\"0.8.8+commit.dddeac2f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"holder\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TestToken.sol\":\"TestToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"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\",\"keccak256\":\"0x4ffc0547c02ad22925310c585c0f166f8759e2648a09e9b489100c42f15dd98d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/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\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/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\",\"keccak256\":\"0x5d96973c72b760b4d49d2f2211829827839ef6593a1a4924196c84a999dcc6c1\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051806040016040528060098152602001682a32b9ba2a37b5b2b760b91b815250604051806040016040528060038152602001621514d560ea1b8152508160039080519060200190610065929190610081565b508051610079906004906020840190610081565b505050610155565b82805461008d9061011a565b90600052602060002090601f0160209004810192826100af57600085556100f5565b82601f106100c857805160ff19168380011785556100f5565b828001600101855582156100f5579182015b828111156100f55782518255916020019190600101906100da565b50610101929150610105565b5090565b5b808211156101015760008155600101610106565b600181811c9082168061012e57607f821691505b6020821081141561014f57634e487b7160e01b600052602260045260246000fd5b50919050565b610a46806101646000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806340c10f1911610081578063a457c2d71161005b578063a457c2d7146101a7578063a9059cbb146101ba578063dd62ed3e146101cd57600080fd5b806340c10f191461016157806370a082311461017657806395d89b411461019f57600080fd5b806323b872dd116100b257806323b872dd1461012c578063313ce5671461013f578063395093511461014e57600080fd5b806306fdde03146100d9578063095ea7b3146100f757806318160ddd1461011a575b600080fd5b6100e1610206565b6040516100ee9190610883565b60405180910390f35b61010a6101053660046108f4565b610298565b60405190151581526020016100ee565b6002545b6040519081526020016100ee565b61010a61013a36600461091e565b6102b0565b604051601281526020016100ee565b61010a61015c3660046108f4565b6102d4565b61017461016f3660046108f4565b610313565b005b61011e61018436600461095a565b6001600160a01b031660009081526020819052604090205490565b6100e1610321565b61010a6101b53660046108f4565b610330565b61010a6101c83660046108f4565b6103df565b61011e6101db36600461097c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b606060038054610215906109af565b80601f0160208091040260200160405190810160405280929190818152602001828054610241906109af565b801561028e5780601f106102635761010080835404028352916020019161028e565b820191906000526020600020905b81548152906001019060200180831161027157829003601f168201915b5050505050905090565b6000336102a68185856103ed565b5060019392505050565b6000336102be858285610545565b6102c98585856105d7565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906102a6908290869061030e9087906109ea565b6103ed565b61031d82826107c4565b5050565b606060048054610215906109af565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103d25760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c982868684036103ed565b6000336102a68185856105d7565b6001600160a01b0383166104685760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0382166104e45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105d157818110156105c45760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103c9565b6105d184848484036103ed565b50505050565b6001600160a01b0383166106535760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0382166106cf5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0383166000908152602081905260409020548181101561075e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105d1565b6001600160a01b03821661081a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103c9565b806002600082825461082c91906109ea565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b818110156108b057858101830151858201604001528201610894565b818111156108c2576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146108ef57600080fd5b919050565b6000806040838503121561090757600080fd5b610910836108d8565b946020939093013593505050565b60008060006060848603121561093357600080fd5b61093c846108d8565b925061094a602085016108d8565b9150604084013590509250925092565b60006020828403121561096c57600080fd5b610975826108d8565b9392505050565b6000806040838503121561098f57600080fd5b610998836108d8565b91506109a6602084016108d8565b90509250929050565b600181811c908216806109c357607f821691505b602082108114156109e457634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115610a0b57634e487b7160e01b600052601160045260246000fd5b50019056fea2646970667358221220c6619aa6dbd9bec1296ef2ec84d724840a2e5985a94f66906481ff3695f3ca9764736f6c63430008080033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806340c10f1911610081578063a457c2d71161005b578063a457c2d7146101a7578063a9059cbb146101ba578063dd62ed3e146101cd57600080fd5b806340c10f191461016157806370a082311461017657806395d89b411461019f57600080fd5b806323b872dd116100b257806323b872dd1461012c578063313ce5671461013f578063395093511461014e57600080fd5b806306fdde03146100d9578063095ea7b3146100f757806318160ddd1461011a575b600080fd5b6100e1610206565b6040516100ee9190610883565b60405180910390f35b61010a6101053660046108f4565b610298565b60405190151581526020016100ee565b6002545b6040519081526020016100ee565b61010a61013a36600461091e565b6102b0565b604051601281526020016100ee565b61010a61015c3660046108f4565b6102d4565b61017461016f3660046108f4565b610313565b005b61011e61018436600461095a565b6001600160a01b031660009081526020819052604090205490565b6100e1610321565b61010a6101b53660046108f4565b610330565b61010a6101c83660046108f4565b6103df565b61011e6101db36600461097c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b606060038054610215906109af565b80601f0160208091040260200160405190810160405280929190818152602001828054610241906109af565b801561028e5780601f106102635761010080835404028352916020019161028e565b820191906000526020600020905b81548152906001019060200180831161027157829003601f168201915b5050505050905090565b6000336102a68185856103ed565b5060019392505050565b6000336102be858285610545565b6102c98585856105d7565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906102a6908290869061030e9087906109ea565b6103ed565b61031d82826107c4565b5050565b606060048054610215906109af565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156103d25760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c982868684036103ed565b6000336102a68185856105d7565b6001600160a01b0383166104685760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0382166104e45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105d157818110156105c45760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103c9565b6105d184848484036103ed565b50505050565b6001600160a01b0383166106535760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0382166106cf5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b0383166000908152602081905260409020548181101561075e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103c9565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105d1565b6001600160a01b03821661081a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103c9565b806002600082825461082c91906109ea565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b818110156108b057858101830151858201604001528201610894565b818111156108c2576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146108ef57600080fd5b919050565b6000806040838503121561090757600080fd5b610910836108d8565b946020939093013593505050565b60008060006060848603121561093357600080fd5b61093c846108d8565b925061094a602085016108d8565b9150604084013590509250925092565b60006020828403121561096c57600080fd5b610975826108d8565b9392505050565b6000806040838503121561098f57600080fd5b610998836108d8565b91506109a6602084016108d8565b90509250929050565b600181811c908216806109c357607f821691505b602082108114156109e457634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115610a0b57634e487b7160e01b600052601160045260246000fd5b50019056fea2646970667358221220c6619aa6dbd9bec1296ef2ec84d724840a2e5985a94f66906481ff3695f3ca9764736f6c63430008080033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 15, + "contract": "contracts/TestToken.sol:TestToken", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 21, + "contract": "contracts/TestToken.sol:TestToken", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 23, + "contract": "contracts/TestToken.sol:TestToken", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 25, + "contract": "contracts/TestToken.sol:TestToken", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 27, + "contract": "contracts/TestToken.sol:TestToken", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/taiko_test/solcInputs/9671d4e1820229dcd69b349a99feb65b.json b/deployments/taiko_test/solcInputs/9671d4e1820229dcd69b349a99feb65b.json new file mode 100644 index 0000000..0912a52 --- /dev/null +++ b/deployments/taiko_test/solcInputs/9671d4e1820229dcd69b349a99feb65b.json @@ -0,0 +1,65 @@ +{ + "language": "Solidity", + "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" + }, + "@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/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" + }, + "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" + } + }, + "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 diff --git a/deployments/taiko_test/solcInputs/e700509efb579c8cd23fdb7d2aca156d.json b/deployments/taiko_test/solcInputs/e700509efb579c8cd23fdb7d2aca156d.json new file mode 100644 index 0000000..2c760e3 --- /dev/null +++ b/deployments/taiko_test/solcInputs/e700509efb579c8cd23fdb7d2aca156d.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\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(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(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);\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, 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 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 {\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) {\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 _marketplaceTotals.sent += 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 {\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 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 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