From b181639bb6b513127245dd8bee5a8cb59bfce27b Mon Sep 17 00:00:00 2001 From: Slava <20563034+veaceslavdoina@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:43:22 +0200 Subject: [PATCH] Add codex_testnet deployment artifacts (#204) https://github.com/codex-storage/nim-codex/issues/1000 --- deployments/codex_testnet/Marketplace.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/deployments/codex_testnet/Marketplace.json b/deployments/codex_testnet/Marketplace.json index 37f8863..34164b8 100644 --- a/deployments/codex_testnet/Marketplace.json +++ b/deployments/codex_testnet/Marketplace.json @@ -1,5 +1,5 @@ { - "address": "0x5Bd66fA15Eb0E546cd26808248867a572cFF5706", + "address": "0xAB03b6a58C5262f530D54146DA2a552B1C0F7648", "abi": [ { "inputs": [ @@ -1195,18 +1195,18 @@ "type": "function" } ], - "transactionHash": "0x7952ab76c12b7e6e747f09fa9eb501117df9c963c9dcc93d092bcfade9dd0b3d", + "transactionHash": "0x843fa3e4fa0998932d199d36a84f826b98b438df57b270650e9bb9f4a1555d4d", "receipt": { "to": null, "from": "0x3A39904B71595608524274BFD8c20FCfd9e77236", - "contractAddress": "0x5Bd66fA15Eb0E546cd26808248867a572cFF5706", + "contractAddress": "0xAB03b6a58C5262f530D54146DA2a552B1C0F7648", "transactionIndex": 0, "gasUsed": "3845908", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x43f389e7936211e63dce1367ac3cc470d48693dcd126ea52e76676a499a45695", - "transactionHash": "0x7952ab76c12b7e6e747f09fa9eb501117df9c963c9dcc93d092bcfade9dd0b3d", + "blockHash": "0x82f6fa49bc02de898ea985aeddf904c8cee2a758e81e8f003f79a13ced079979", + "transactionHash": "0x843fa3e4fa0998932d199d36a84f826b98b438df57b270650e9bb9f4a1555d4d", "logs": [], - "blockNumber": 2028587, + "blockNumber": 2222689, "cumulativeGasUsed": "3845908", "status": 1, "byzantium": true @@ -1220,7 +1220,7 @@ "slashPercentage": 20 }, "proofs": { - "period": 60, + "period": 120, "timeout": 30, "downtime": 64, "downtimeProduct": 67, @@ -1233,7 +1233,7 @@ "0x34a22f3911De437307c6f4485931779670f78764", "0x02dd582726F7507D7d0F8bD8bf8053d3006F9092" ], - "numDeployments": 5, + "numDeployments": 6, "solcInputHash": "6c0b1ecc717fd79335563520a885156c", "metadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"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\":\"string\",\"name\":\"zkeyHash\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"downtimeProduct\",\"type\":\"uint8\"}],\"internalType\":\"struct ProofConfig\",\"name\":\"proofs\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"maxReservations\",\"type\":\"uint8\"}],\"internalType\":\"struct SlotReservationsConfig\",\"name\":\"reservations\",\"type\":\"tuple\"}],\"internalType\":\"struct MarketplaceConfig\",\"name\":\"configuration\",\"type\":\"tuple\"},{\"internalType\":\"contract IERC20\",\"name\":\"token_\",\"type\":\"address\"},{\"internalType\":\"contract IGroth16Verifier\",\"name\":\"verifier\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"SlotId\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"ProofSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"SlotFilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"SlotFreed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"SlotReservationsFull\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"slots\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"slotSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofProbability\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"maxSlotLoss\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"struct Ask\",\"name\":\"ask\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"}],\"name\":\"StorageRequested\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"canReserveSlot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"configuration\",\"outputs\":[{\"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\":\"string\",\"name\":\"zkeyHash\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"downtimeProduct\",\"type\":\"uint8\"}],\"internalType\":\"struct ProofConfig\",\"name\":\"proofs\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"maxReservations\",\"type\":\"uint8\"}],\"internalType\":\"struct SlotReservationsConfig\",\"name\":\"reservations\",\"type\":\"tuple\"}],\"internalType\":\"struct MarketplaceConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct G1Point\",\"name\":\"a\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"real\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"imag\",\"type\":\"uint256\"}],\"internalType\":\"struct Fp2Element\",\"name\":\"x\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"real\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"imag\",\"type\":\"uint256\"}],\"internalType\":\"struct Fp2Element\",\"name\":\"y\",\"type\":\"tuple\"}],\"internalType\":\"struct G2Point\",\"name\":\"b\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct G1Point\",\"name\":\"c\",\"type\":\"tuple\"}],\"internalType\":\"struct Groth16Proof\",\"name\":\"proof\",\"type\":\"tuple\"}],\"name\":\"fillSlot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"SlotId\",\"name\":\"slotId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"collateralRecipient\",\"type\":\"address\"}],\"name\":\"freeSlot\",\"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\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"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\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"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\":\"requestExpiry\",\"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\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"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\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"slotIndex\",\"type\":\"uint256\"}],\"name\":\"reserveSlot\",\"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\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct G1Point\",\"name\":\"a\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"real\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"imag\",\"type\":\"uint256\"}],\"internalType\":\"struct Fp2Element\",\"name\":\"x\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"real\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"imag\",\"type\":\"uint256\"}],\"internalType\":\"struct Fp2Element\",\"name\":\"y\",\"type\":\"tuple\"}],\"internalType\":\"struct G2Point\",\"name\":\"b\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct G1Point\",\"name\":\"c\",\"type\":\"tuple\"}],\"internalType\":\"struct Groth16Proof\",\"name\":\"proof\",\"type\":\"tuple\"}],\"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\"},{\"inputs\":[{\"internalType\":\"RequestId\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"withdrawRecipient\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"fillSlot(bytes32,uint256,((uint256,uint256),((uint256,uint256),(uint256,uint256)),(uint256,uint256)))\":{\"params\":{\"proof\":\"Groth16 proof procing possession of the slot data.\",\"requestId\":\"RequestId identifying the request containing the slot to fill.\",\"slotIndex\":\"Index of the slot in the request.\"}},\"freeSlot(bytes32)\":{\"details\":\"The host that filled the slot must have initiated the transaction (msg.sender). This overload allows `rewardRecipient` and `collateralRecipient` to be optional.\",\"params\":{\"slotId\":\"id of the slot to free\"}},\"freeSlot(bytes32,address,address)\":{\"params\":{\"collateralRecipient\":\"address to refund collateral to\",\"rewardRecipient\":\"address to send rewards to\",\"slotId\":\"id of the slot to free\"}},\"getChallenge(bytes32)\":{\"params\":{\"id\":\"Slot's ID for which the challenge should be calculated\"},\"returns\":{\"_0\":\"Challenge for current Period that should be used for generation of proofs\"}},\"getPointer(bytes32)\":{\"details\":\"For more information see [timing of storage proofs](https://github.com/codex-storage/codex-research/blob/41c4b4409d2092d0a5475aca0f28995034e58d14/design/storage-proof-timing.md)\",\"params\":{\"id\":\"Slot's ID for which the pointer should be calculated\"},\"returns\":{\"_0\":\"Uint8 pointer that is stable over current Period, ie an integer offset [0-255] of the last 256 blocks, pointing to a block that remains constant for the entire Period's duration.\"}},\"isProofRequired(bytes32)\":{\"params\":{\"id\":\"Slot's ID for which the proof requirements should be checked. If the Slot's state is other than Filled, `false` is always returned.\"},\"returns\":{\"_0\":\"bool indicating if proof is required for current period\"}},\"missingProofs(bytes32)\":{\"returns\":{\"_0\":\"Number of missed proofs since Slot was Filled\"}},\"willProofBeRequired(bytes32)\":{\"details\":\"for more info about downtime see [timing of storage proofs](https://github.com/codex-storage/codex-research/blob/41c4b4409d2092d0a5475aca0f28995034e58d14/design/storage-proof-timing.md#pointer-downtime)\",\"params\":{\"id\":\"SlotId for which the proof requirements should be checked. If the Slot's state is other than Filled, `false` is always returned.\"},\"returns\":{\"_0\":\"bool\"}},\"withdrawFunds(bytes32)\":{\"details\":\"Request must be cancelled, failed or finished, and the transaction must originate from the depositor address.\",\"params\":{\"requestId\":\"the id of the request\"}},\"withdrawFunds(bytes32,address)\":{\"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\",\"withdrawRecipient\":\"address to return the remaining funds to\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"fillSlot(bytes32,uint256,((uint256,uint256),((uint256,uint256),(uint256,uint256)),(uint256,uint256)))\":{\"notice\":\"Fills a slot. Reverts if an invalid proof of the slot data is provided.\"},\"freeSlot(bytes32)\":{\"notice\":\"Frees a slot, paying out rewards and returning collateral for finished or cancelled requests to the host that has filled the slot.\"},\"freeSlot(bytes32,address,address)\":{\"notice\":\"Frees a slot, paying out rewards and returning collateral for finished or cancelled requests.\"},\"willProofBeRequired(bytes32)\":{\"notice\":\"Proof Downtime specifies part of the Period when the proof is not required even if the proof should be required. This function returns true if the pointer is in downtime (hence no proof required now) and at the same time the proof will be required later on in the Period.\"},\"withdrawFunds(bytes32)\":{\"notice\":\"Withdraws remaining storage request funds back to the client that deposited them.\"},\"withdrawFunds(bytes32,address)\":{\"notice\":\"Withdraws storage request funds to the provided address.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Marketplace.sol\":\"Marketplace\"},\"evmVersion\":\"paris\",\"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.23;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nstruct MarketplaceConfig {\\n CollateralConfig collateral;\\n ProofConfig proofs;\\n SlotReservationsConfig reservations;\\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 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 string zkeyHash; // hash of the zkey file which is linked to the verifier\\n // Ensures the pointer does not remain in downtime for many consecutive\\n // periods. For each period increase, move the pointer `pointerProduct`\\n // blocks. Should be a prime number to ensure there are no cycles.\\n uint8 downtimeProduct;\\n}\\n\\nstruct SlotReservationsConfig {\\n // Number of allowed reservations per slot\\n uint8 maxReservations;\\n}\\n\",\"keccak256\":\"0x76c7a6183e1031680ffc3e3a0bd52d257d43ee7311aebdd542949894dfddf9ac\",\"license\":\"MIT\"},\"contracts/Endian.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\ncontract Endian {\\n /// reverses byte order to allow conversion between little endian and big\\n /// endian integers\\n function _byteSwap(bytes32 input) internal pure returns (bytes32 output) {\\n output = output | bytes1(input);\\n for (uint i = 1; i < 32; i++) {\\n output = output >> 8;\\n output = output | bytes1(input << (i * 8));\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6acc2a19aaedc1b903681fedf6e302aabdd33695dee215e21b5190a83d0769e\",\"license\":\"MIT\"},\"contracts/Groth16.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\nstruct G1Point {\\n uint256 x;\\n uint256 y;\\n}\\n\\n// A field element F_{p^2} encoded as `real + i * imag`.\\n// We chose to not represent this as an array of 2 numbers, because both Circom\\n// and Ethereum EIP-197 encode to an array, but with conflicting encodings.\\nstruct Fp2Element {\\n uint256 real;\\n uint256 imag;\\n}\\n\\nstruct G2Point {\\n Fp2Element x;\\n Fp2Element y;\\n}\\n\\nstruct Groth16Proof {\\n G1Point a;\\n G2Point b;\\n G1Point c;\\n}\\n\\ninterface IGroth16Verifier {\\n function verify(\\n Groth16Proof calldata proof,\\n uint256[] calldata pubSignals\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xe1c7a8730cf718c9b69052c81ca3241d7f61c25f3d7944962077d768bf601baf\",\"license\":\"MIT\"},\"contracts/Marketplace.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\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 \\\"./SlotReservations.sol\\\";\\nimport \\\"./StateRetrieval.sol\\\";\\nimport \\\"./Endian.sol\\\";\\nimport \\\"./Groth16.sol\\\";\\n\\ncontract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using Requests for Request;\\n\\n IERC20 private immutable _token;\\n MarketplaceConfig private _config;\\n\\n mapping(RequestId => Request) private _requests;\\n mapping(RequestId => RequestContext) internal _requestContexts;\\n mapping(SlotId => Slot) internal _slots;\\n\\n MarketplaceTotals internal _marketplaceTotals;\\n\\n struct RequestContext {\\n RequestState state;\\n uint256 slotsFilled;\\n /// @notice Tracks how much funds should be returned to the client as not all funds might be used for hosting the request\\n /// @dev The sum starts with the full reward amount for the request and is reduced every time a host fills a slot.\\n /// The reduction is calculated from the duration of time between the slot being filled and the request's end.\\n /// This is the amount that will be paid out to the host when the request successfully finishes.\\n /// @dev fundsToReturnToClient == 0 is used to signal that after request is terminated all the remaining funds were withdrawn.\\n /// This is possible, because technically it is not possible for this variable to reach 0 in \\\"natural\\\" way as\\n /// that would require all the slots to be filled at the same block as the request was created.\\n uint256 fundsToReturnToClient;\\n uint256 startedAt;\\n uint256 endsAt;\\n uint256 expiresAt;\\n }\\n\\n struct Slot {\\n SlotState state;\\n RequestId requestId;\\n /// @notice Timestamp that signals when slot was filled\\n /// @dev Used for calculating payouts as hosts are paid based on time they actually host the content\\n uint256 filledAt;\\n uint256 slotIndex;\\n /// @notice Tracks the current amount of host's collateral that is to be payed out at the end of Slot's lifespan.\\n /// @dev When Slot is filled, the collateral is collected in amount of request.ask.collateral\\n /// @dev When Host is slashed for missing a proof the slashed amount is reflected in this variable\\n uint256 currentCollateral;\\n address host; // address used for collateral interactions and identifying hosts\\n }\\n\\n struct ActiveSlot {\\n Request request;\\n uint256 slotIndex;\\n }\\n\\n constructor(\\n MarketplaceConfig memory configuration,\\n IERC20 token_,\\n IGroth16Verifier verifier\\n )\\n SlotReservations(configuration.reservations)\\n Proofs(configuration.proofs, verifier)\\n {\\n _token = token_;\\n\\n require(\\n configuration.collateral.repairRewardPercentage <= 100,\\n \\\"Must be less than 100\\\"\\n );\\n require(\\n configuration.collateral.slashPercentage <= 100,\\n \\\"Must be less than 100\\\"\\n );\\n require(\\n configuration.collateral.maxNumberOfSlashes *\\n configuration.collateral.slashPercentage <=\\n 100,\\n \\\"Maximum slashing exceeds 100%\\\"\\n );\\n _config = configuration;\\n }\\n\\n function configuration() public view returns (MarketplaceConfig memory) {\\n return _config;\\n }\\n\\n function token() public view returns (IERC20) {\\n return _token;\\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 require(\\n request.expiry > 0 && request.expiry < request.ask.duration,\\n \\\"Expiry not in range\\\"\\n );\\n require(request.ask.slots > 0, \\\"Insufficient slots\\\");\\n require(\\n request.ask.maxSlotLoss <= request.ask.slots,\\n \\\"maxSlotLoss exceeds slots\\\"\\n );\\n\\n _requests[id] = request;\\n _requestContexts[id].endsAt = block.timestamp + request.ask.duration;\\n _requestContexts[id].expiresAt = block.timestamp + request.expiry;\\n\\n _addToMyRequests(request.client, id);\\n\\n uint256 amount = request.maxPrice();\\n _requestContexts[id].fundsToReturnToClient = amount;\\n _marketplaceTotals.received += amount;\\n _transferFrom(msg.sender, amount);\\n\\n emit StorageRequested(id, request.ask, _requestContexts[id].expiresAt);\\n }\\n\\n /**\\n * @notice Fills a slot. Reverts if an invalid proof of the slot data is\\n provided.\\n * @param requestId RequestId identifying the request containing the slot to\\n fill.\\n * @param slotIndex Index of the slot in the request.\\n * @param proof Groth16 proof procing possession of the slot data.\\n */\\n function fillSlot(\\n RequestId requestId,\\n uint256 slotIndex,\\n Groth16Proof 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 require(_reservations[slotId].contains(msg.sender), \\\"Reservation required\\\");\\n\\n Slot storage slot = _slots[slotId];\\n slot.requestId = requestId;\\n slot.slotIndex = slotIndex;\\n RequestContext storage context = _requestContexts[requestId];\\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 slot.filledAt = block.timestamp;\\n\\n context.slotsFilled += 1;\\n context.fundsToReturnToClient -= _slotPayout(requestId, slot.filledAt);\\n\\n // Collect collateral\\n uint256 collateralAmount = request.ask.collateral;\\n _transferFrom(msg.sender, collateralAmount);\\n _marketplaceTotals.received += collateralAmount;\\n slot.currentCollateral = collateralAmount;\\n\\n _addToMySlots(slot.host, slotId);\\n\\n emit SlotFilled(requestId, slotIndex);\\n if (context.slotsFilled == request.ask.slots) {\\n context.state = RequestState.Started;\\n context.startedAt = block.timestamp;\\n emit RequestFulfilled(requestId);\\n }\\n }\\n\\n /**\\n * @notice Frees a slot, paying out rewards and returning collateral for\\n finished or cancelled requests to the host that has filled the slot.\\n * @param slotId id of the slot to free\\n * @dev The host that filled the slot must have initiated the transaction\\n (msg.sender). This overload allows `rewardRecipient` and\\n `collateralRecipient` to be optional.\\n */\\n function freeSlot(SlotId slotId) public slotIsNotFree(slotId) {\\n return freeSlot(slotId, msg.sender, msg.sender);\\n }\\n\\n /**\\n * @notice Frees a slot, paying out rewards and returning collateral for\\n finished or cancelled requests.\\n * @param slotId id of the slot to free\\n * @param rewardRecipient address to send rewards to\\n * @param collateralRecipient address to refund collateral to\\n */\\n function freeSlot(\\n SlotId slotId,\\n address rewardRecipient,\\n address collateralRecipient\\n ) 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, rewardRecipient, collateralRecipient);\\n } else if (state == SlotState.Cancelled) {\\n _payoutCancelledSlot(\\n slot.requestId,\\n slotId,\\n rewardRecipient,\\n collateralRecipient\\n );\\n } else if (state == SlotState.Failed) {\\n _removeFromMySlots(msg.sender, slotId);\\n } else if (state == SlotState.Filled) {\\n // free slot without returning collateral, effectively a 100% slash\\n _forciblyFreeSlot(slotId);\\n }\\n }\\n\\n function _challengeToFieldElement(\\n bytes32 challenge\\n ) internal pure returns (uint256) {\\n // use only 31 bytes of the challenge to ensure that it fits into the field\\n bytes32 truncated = bytes32(bytes31(challenge));\\n // convert from little endian to big endian\\n bytes32 bigEndian = _byteSwap(truncated);\\n // convert bytes to integer\\n return uint256(bigEndian);\\n }\\n\\n function _merkleRootToFieldElement(\\n bytes32 merkleRoot\\n ) internal pure returns (uint256) {\\n // convert from little endian to big endian\\n bytes32 bigEndian = _byteSwap(merkleRoot);\\n // convert bytes to integer\\n return uint256(bigEndian);\\n }\\n\\n function submitProof(\\n SlotId id,\\n Groth16Proof calldata proof\\n ) public requestIsKnown(_slots[id].requestId) {\\n Slot storage slot = _slots[id];\\n Request storage request = _requests[slot.requestId];\\n uint256[] memory pubSignals = new uint256[](3);\\n pubSignals[0] = _challengeToFieldElement(getChallenge(id));\\n pubSignals[1] = _merkleRootToFieldElement(request.content.merkleRoot);\\n pubSignals[2] = slot.slotIndex;\\n _proofReceived(id, proof, pubSignals);\\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 // TODO: Reward for validator that calls this function\\n\\n if (missingProofs(slotId) % _config.collateral.slashCriterion == 0) {\\n uint256 slashedAmount = (request.ask.collateral *\\n _config.collateral.slashPercentage) / 100;\\n slot.currentCollateral -= slashedAmount;\\n if (\\n missingProofs(slotId) / _config.collateral.slashCriterion >=\\n _config.collateral.maxNumberOfSlashes\\n ) {\\n // When the number of slashings is at or above the allowed amount,\\n // free the slot.\\n _forciblyFreeSlot(slotId);\\n }\\n }\\n }\\n\\n /**\\n * @notice Abandons the slot without returning collateral, effectively slashing the\\n entire collateral.\\n * @param slotId SlotId of the slot to free.\\n * @dev _slots[slotId] is deleted, resetting _slots[slotId].currentCollateral\\n to 0.\\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 // We need to refund the amount of payout of the current node to the `fundsToReturnToClient` so\\n // we keep correctly the track of the funds that needs to be returned at the end.\\n context.fundsToReturnToClient += _slotPayout(requestId, slot.filledAt);\\n\\n _removeFromMySlots(slot.host, slotId);\\n uint256 slotIndex = slot.slotIndex;\\n delete _slots[slotId];\\n context.slotsFilled -= 1;\\n emit SlotFreed(requestId, slotIndex);\\n _resetMissingProofs(slotId);\\n\\n Request storage request = _requests[requestId];\\n uint256 slotsLost = request.ask.slots - context.slotsFilled;\\n if (\\n slotsLost > request.ask.maxSlotLoss &&\\n context.state == RequestState.Started\\n ) {\\n context.state = RequestState.Failed;\\n context.endsAt = block.timestamp - 1;\\n emit RequestFailed(requestId);\\n }\\n }\\n\\n function _payoutSlot(\\n RequestId requestId,\\n SlotId slotId,\\n address rewardRecipient,\\n address collateralRecipient\\n ) private requestIsKnown(requestId) {\\n RequestContext storage context = _requestContexts[requestId];\\n Request storage request = _requests[requestId];\\n context.state = RequestState.Finished;\\n Slot storage slot = _slots[slotId];\\n\\n _removeFromMyRequests(request.client, requestId);\\n _removeFromMySlots(slot.host, slotId);\\n\\n uint256 payoutAmount = _slotPayout(requestId, slot.filledAt);\\n uint256 collateralAmount = slot.currentCollateral;\\n _marketplaceTotals.sent += (payoutAmount + collateralAmount);\\n slot.state = SlotState.Paid;\\n assert(_token.transfer(rewardRecipient, payoutAmount));\\n assert(_token.transfer(collateralRecipient, collateralAmount));\\n }\\n\\n /**\\n * @notice Pays out a host for duration of time that the slot was filled, and\\n returns the collateral.\\n * @dev The payouts are sent to the rewardRecipient, and collateral is returned\\n to the host address.\\n * @param requestId RequestId of the request that contains the slot to be paid\\n out.\\n * @param slotId SlotId of the slot to be paid out.\\n */\\n function _payoutCancelledSlot(\\n RequestId requestId,\\n SlotId slotId,\\n address rewardRecipient,\\n address collateralRecipient\\n ) private requestIsKnown(requestId) {\\n Slot storage slot = _slots[slotId];\\n _removeFromMySlots(slot.host, slotId);\\n\\n uint256 payoutAmount = _slotPayout(\\n requestId,\\n slot.filledAt,\\n requestExpiry(requestId)\\n );\\n uint256 collateralAmount = slot.currentCollateral;\\n _marketplaceTotals.sent += (payoutAmount + collateralAmount);\\n slot.state = SlotState.Paid;\\n assert(_token.transfer(rewardRecipient, payoutAmount));\\n assert(_token.transfer(collateralRecipient, collateralAmount));\\n }\\n\\n /**\\n * @notice Withdraws remaining storage request funds back to the client that\\n deposited them.\\n * @dev Request must be cancelled, failed or finished, and the\\n transaction must originate from the depositor address.\\n * @param requestId the id of the request\\n */\\n function withdrawFunds(RequestId requestId) public {\\n withdrawFunds(requestId, msg.sender);\\n }\\n\\n /**\\n * @notice Withdraws storage request funds to the provided address.\\n * @dev Request must be expired, must be in RequestState.New, and the\\n transaction must originate from the depositer address.\\n * @param requestId the id of the request\\n * @param withdrawRecipient address to return the remaining funds to\\n */\\n function withdrawFunds(\\n RequestId requestId,\\n address withdrawRecipient\\n ) public {\\n Request storage request = _requests[requestId];\\n require(request.client == msg.sender, \\\"Invalid client address\\\");\\n RequestContext storage context = _requestContexts[requestId];\\n RequestState state = requestState(requestId);\\n require(\\n state == RequestState.Cancelled ||\\n state == RequestState.Failed ||\\n state == RequestState.Finished,\\n \\\"Invalid state\\\"\\n );\\n\\n // fundsToReturnToClient == 0 is used for \\\"double-spend\\\" protection, once the funds are withdrawn\\n // then this variable is set to 0.\\n require(context.fundsToReturnToClient != 0, \\\"Nothing to withdraw\\\");\\n\\n if (state == RequestState.Cancelled) {\\n context.state = RequestState.Cancelled;\\n emit RequestCancelled(requestId);\\n\\n // `fundsToReturnToClient` currently tracks funds to be returned for requests that successfully finish.\\n // When requests are cancelled, funds earmarked for payment for the duration\\n // between request expiry and request end (for every slot that was filled), should be returned to the client.\\n // Update `fundsToReturnToClient` to reflect this.\\n context.fundsToReturnToClient +=\\n context.slotsFilled *\\n _slotPayout(requestId, requestExpiry(requestId));\\n } else if (state == RequestState.Failed) {\\n // For Failed requests the client is refunded whole amount.\\n context.fundsToReturnToClient = request.maxPrice();\\n } else {\\n context.state = RequestState.Finished;\\n }\\n\\n _removeFromMyRequests(request.client, requestId);\\n\\n uint256 amount = context.fundsToReturnToClient;\\n _marketplaceTotals.sent += amount;\\n assert(_token.transfer(withdrawRecipient, amount));\\n\\n // We zero out the funds tracking in order to prevent double-spends\\n context.fundsToReturnToClient = 0;\\n }\\n\\n function getActiveSlot(\\n SlotId slotId\\n ) public view slotIsNotFree(slotId) returns (ActiveSlot memory) {\\n Slot storage slot = _slots[slotId];\\n ActiveSlot memory activeSlot;\\n activeSlot.request = _requests[slot.requestId];\\n activeSlot.slotIndex = slot.slotIndex;\\n return activeSlot;\\n }\\n\\n modifier requestIsKnown(RequestId requestId) {\\n require(_requests[requestId].client != address(0), \\\"Unknown request\\\");\\n _;\\n }\\n\\n function getRequest(\\n RequestId requestId\\n ) public view requestIsKnown(requestId) returns (Request memory) {\\n return _requests[requestId];\\n }\\n\\n modifier slotIsNotFree(SlotId slotId) {\\n require(_slots[slotId].state != SlotState.Free, \\\"Slot is free\\\");\\n _;\\n }\\n\\n function _slotIsFree(SlotId slotId) internal view override returns (bool) {\\n return _slots[slotId].state == SlotState.Free;\\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 requestExpiry(RequestId requestId) public view returns (uint256) {\\n return _requestContexts[requestId].expiresAt;\\n }\\n\\n /**\\n * @notice Calculates the amount that should be paid out to a host that successfully finished the request\\n * @param requestId RequestId of the request used to calculate the payout\\n * amount.\\n * @param startingTimestamp timestamp indicating when a host filled a slot and\\n * started providing proofs.\\n */\\n function _slotPayout(\\n RequestId requestId,\\n uint256 startingTimestamp\\n ) private view returns (uint256) {\\n return\\n _slotPayout(\\n requestId,\\n startingTimestamp,\\n _requestContexts[requestId].endsAt\\n );\\n }\\n\\n /// @notice Calculates the amount that should be paid out to a host based on the specified time frame.\\n function _slotPayout(\\n RequestId requestId,\\n uint256 startingTimestamp,\\n uint256 endingTimestamp\\n ) private view returns (uint256) {\\n Request storage request = _requests[requestId];\\n require(startingTimestamp < endingTimestamp, \\\"Start not before expiry\\\");\\n\\n return (endingTimestamp - startingTimestamp) * request.ask.reward;\\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 > requestExpiry(requestId)\\n ) {\\n return RequestState.Cancelled;\\n } else if (\\n (context.state == RequestState.Started ||\\n context.state == RequestState.New) && 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.Cancelled;\\n }\\n if (reqState == RequestState.Finished) {\\n return SlotState.Finished;\\n }\\n if (reqState == RequestState.Failed) {\\n return SlotState.Failed;\\n }\\n return slot.state;\\n }\\n\\n function _transferFrom(address sender, uint256 amount) internal {\\n address receiver = address(this);\\n require(_token.transferFrom(sender, receiver, amount), \\\"Transfer failed\\\");\\n }\\n\\n event StorageRequested(RequestId requestId, Ask ask, uint256 expiry);\\n event RequestFulfilled(RequestId indexed requestId);\\n event RequestFailed(RequestId indexed requestId);\\n event SlotFilled(RequestId indexed requestId, uint256 slotIndex);\\n event SlotFreed(RequestId indexed requestId, uint256 slotIndex);\\n event RequestCancelled(RequestId indexed requestId);\\n\\n struct MarketplaceTotals {\\n uint256 received;\\n uint256 sent;\\n }\\n}\\n\",\"keccak256\":\"0xb688389c237542e928d2687f1597eacf0025e4780dfa477bb88fd1df984935d8\",\"license\":\"MIT\"},\"contracts/Periods.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\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\":\"0xd70cb0ff823e635a1f52f39d8d32451d2d17d2588dc0a894d28432af72f878ff\",\"license\":\"MIT\"},\"contracts/Proofs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\nimport \\\"./Configuration.sol\\\";\\nimport \\\"./Requests.sol\\\";\\nimport \\\"./Periods.sol\\\";\\nimport \\\"./Groth16.sol\\\";\\n\\n/**\\n * @title Proofs\\n * @notice Abstract contract that handles proofs tracking, validation and reporting functionality\\n */\\nabstract contract Proofs is Periods {\\n ProofConfig private _config;\\n IGroth16Verifier private _verifier;\\n\\n /**\\n * Creation of the contract requires at least 256 mined blocks!\\n * @param config Proving configuration\\n */\\n constructor(\\n ProofConfig memory config,\\n IGroth16Verifier verifier\\n ) Periods(config.period) {\\n require(block.number > 256, \\\"Insufficient block height\\\");\\n _config = config;\\n _verifier = verifier;\\n }\\n\\n mapping(SlotId => uint256) private _slotStarts; // TODO: Should be smaller than uint256\\n mapping(SlotId => uint256) private _probabilities;\\n mapping(SlotId => uint256) private _missed; // TODO: Should be smaller than uint256\\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 /**\\n * @return Number of missed proofs since Slot was Filled\\n */\\n function missingProofs(SlotId slotId) public view returns (uint256) {\\n return _missed[slotId];\\n }\\n\\n /**\\n * @param slotId Slot's ID for which the proofs should be reset\\n * @notice Resets the missing proofs counter to zero\\n */\\n function _resetMissingProofs(SlotId slotId) internal {\\n _missed[slotId] = 0;\\n }\\n\\n /**\\n * @param id Slot's ID for which the proofs should be started to require\\n * @param probability Integer which specifies the probability of how often the proofs will be required. Lower number means higher probability.\\n * @notice Notes down the block's timestamp as Slot's starting time for requiring proofs\\n * and saves the required probability.\\n */\\n function _startRequiringProofs(SlotId id, uint256 probability) internal {\\n _slotStarts[id] = block.timestamp;\\n _probabilities[id] = probability;\\n }\\n\\n /**\\n * @param id Slot's ID for which the pointer should be calculated\\n * @param period Period for which the pointer should be calculated\\n * @return Uint8 pointer that is stable over current Period, ie an integer offset [0-255] of the last 256 blocks, pointing to a block that remains constant for the entire Period's duration.\\n * @dev For more information see [timing of storage proofs](https://github.com/codex-storage/codex-research/blob/41c4b4409d2092d0a5475aca0f28995034e58d14/design/storage-proof-timing.md)\\n */\\n function _getPointer(SlotId id, Period period) internal view returns (uint8) {\\n uint256 blockNumber = block.number % 256;\\n uint256 periodNumber = (Period.unwrap(period) * _config.downtimeProduct) %\\n 256;\\n uint256 idOffset = uint256(SlotId.unwrap(id)) % 256;\\n uint256 pointer = (blockNumber + periodNumber + idOffset) % 256;\\n return uint8(pointer);\\n }\\n\\n /**\\n * @param id Slot's ID for which the pointer should be calculated\\n * @return Uint8 pointer that is stable over current Period, ie an integer offset [0-255] of the last 256 blocks, pointing to a block that remains constant for the entire Period's duration.\\n * @dev For more information see [timing of storage proofs](https://github.com/codex-storage/codex-research/blob/41c4b4409d2092d0a5475aca0f28995034e58d14/design/storage-proof-timing.md)\\n */\\n function getPointer(SlotId id) public view returns (uint8) {\\n return _getPointer(id, _blockPeriod());\\n }\\n\\n /**\\n * @param pointer Integer [0-255] that indicates an offset of the last 256 blocks, pointing to a block that remains constant for the entire Period's duration.\\n * @return Challenge that should be used for generation of proofs\\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 /**\\n * @param id Slot's ID for which the challenge should be calculated\\n * @param period Period for which the challenge should be calculated\\n * @return Challenge that should be used for generation of proofs\\n */\\n function _getChallenge(\\n SlotId id,\\n Period period\\n ) internal view returns (bytes32) {\\n return _getChallenge(_getPointer(id, period));\\n }\\n\\n /**\\n * @param id Slot's ID for which the challenge should be calculated\\n * @return Challenge for current Period that should be used for generation of proofs\\n */\\n function getChallenge(SlotId id) public view returns (bytes32) {\\n return _getChallenge(id, _blockPeriod());\\n }\\n\\n /**\\n * @param id Slot's ID for which the requirements are gathered. If the Slot's state is other than Filled, `false` is always returned.\\n * @param period Period for which the requirements are gathered.\\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\\n /// Scaling of the probability according the downtime configuration\\n /// See: https://github.com/codex-storage/codex-research/blob/41c4b4409d2092d0a5475aca0f28995034e58d14/design/storage-proof-timing.md#pointer-downtime\\n uint256 probability = (_probabilities[id] * (256 - _config.downtime)) / 256;\\n isRequired = probability == 0 || uint256(challenge) % probability == 0;\\n }\\n\\n /**\\n * See isProofRequired\\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 /**\\n * @param id Slot's ID for which the proof requirements should be checked. If the Slot's state is other than Filled, `false` is always returned.\\n * @return bool indicating if proof is required for current period\\n */\\n function isProofRequired(SlotId id) public view returns (bool) {\\n return _isProofRequired(id, _blockPeriod());\\n }\\n\\n /**\\n * Proof Downtime specifies part of the Period when the proof is not required even\\n * if the proof should be required. This function returns true if the pointer is\\n * in downtime (hence no proof required now) and at the same time the proof\\n * will be required later on in the Period.\\n *\\n * @dev for more info about downtime see [timing of storage proofs](https://github.com/codex-storage/codex-research/blob/41c4b4409d2092d0a5475aca0f28995034e58d14/design/storage-proof-timing.md#pointer-downtime)\\n * @param id SlotId for which the proof requirements should be checked. If the Slot's state is other than Filled, `false` is always returned.\\n * @return bool\\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 /**\\n * Function used for submitting and verification of the proofs.\\n *\\n * @dev Reverts when proof is invalid or had been already submitted.\\n * @dev Emits ProofSubmitted event.\\n * @param id Slot's ID for which the proof requirements should be checked\\n * @param proof Groth16 proof\\n * @param pubSignals Proofs public input\\n */\\n function _proofReceived(\\n SlotId id,\\n Groth16Proof calldata proof,\\n uint[] memory pubSignals\\n ) internal {\\n require(!_received[id][_blockPeriod()], \\\"Proof already submitted\\\");\\n require(_verifier.verify(proof, pubSignals), \\\"Invalid proof\\\");\\n _received[id][_blockPeriod()] = true;\\n emit ProofSubmitted(id);\\n }\\n\\n /**\\n * Function used to mark proof as missing.\\n *\\n * @param id Slot's ID for which the proof is missing\\n * @param missedPeriod Period for which the proof was missed\\n * @dev Reverts when:\\n * - missedPeriod has not ended yet ended\\n * - missing proof was time-barred\\n * - proof was submitted\\n * - proof was not required for missedPeriod period\\n * - proof was already marked as missing\\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);\\n}\\n\",\"keccak256\":\"0x742a491cf61d941b39bc2694dd039917438276f881849922e51fb08360d32ef0\",\"license\":\"MIT\"},\"contracts/Requests.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\ntype RequestId is bytes32;\\ntype SlotId is bytes32;\\n\\nstruct Request {\\n address client;\\n Ask ask;\\n Content content;\\n uint256 expiry; // amount of seconds since start of the request 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, used to download the dataset\\n bytes32 merkleRoot; // merkle root of the dataset, used to verify storage proofs\\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 Cancelled // when request was cancelled then slot is cancelled as well\\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 maxPrice(Request memory request) internal pure returns (uint256) {\\n return request.ask.slots * request.ask.duration * request.ask.reward;\\n }\\n}\\n\",\"keccak256\":\"0x7ade8617cce1ac6149830ad180c07c8b041e6cddb3e8c83ecdd23994b3f13197\",\"license\":\"MIT\"},\"contracts/SlotReservations.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\n\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"./Requests.sol\\\";\\nimport \\\"./Configuration.sol\\\";\\n\\nabstract contract SlotReservations {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(SlotId => EnumerableSet.AddressSet) internal _reservations;\\n SlotReservationsConfig private _config;\\n\\n constructor(SlotReservationsConfig memory config) {\\n _config = config;\\n }\\n\\n function _slotIsFree(SlotId slotId) internal view virtual returns (bool);\\n\\n function reserveSlot(RequestId requestId, uint256 slotIndex) public {\\n require(canReserveSlot(requestId, slotIndex), \\\"Reservation not allowed\\\");\\n\\n SlotId slotId = Requests.slotId(requestId, slotIndex);\\n _reservations[slotId].add(msg.sender);\\n\\n if (_reservations[slotId].length() == _config.maxReservations) {\\n emit SlotReservationsFull(requestId, slotIndex);\\n }\\n }\\n\\n function canReserveSlot(\\n RequestId requestId,\\n uint256 slotIndex\\n ) public view returns (bool) {\\n address host = msg.sender;\\n SlotId slotId = Requests.slotId(requestId, slotIndex);\\n return\\n // TODO: add in check for address inside of expanding window\\n _slotIsFree(slotId) &&\\n (_reservations[slotId].length() < _config.maxReservations) &&\\n (!_reservations[slotId].contains(host));\\n }\\n\\n event SlotReservationsFull(RequestId indexed requestId, uint256 slotIndex);\\n}\\n\",\"keccak256\":\"0xb07acc5f623da7118860fa8f323ecc694052c56b916e5fb79bc20d2f3a642b79\",\"license\":\"MIT\"},\"contracts/StateRetrieval.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.23;\\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\":\"0x734c58b16cd1bf57aed889162708140b4a093698963c5cf688308f7d8b2d5deb\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x60c06040523480156200001157600080fd5b506040516200454b3803806200454b833981016040819052620000349162000571565b602083015180516040850151516001805460ff191660ff909216919091179055608052816101004311620000af5760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420626c6f636b206865696768740000000000000060448201526064015b60405180910390fd5b81516002908155602083015160035560408301516004805460ff191660ff9092169190911790556060830151839190600590620000ed908262000724565b50608091909101516004909101805460ff191660ff928316179055600780546001600160a01b0319166001600160a01b0393841617905590841660a0528451516064911611159050620001835760405162461bcd60e51b815260206004820152601560248201527f4d757374206265206c657373207468616e2031303000000000000000000000006044820152606401620000a6565b606483600001516060015160ff161115620001e15760405162461bcd60e51b815260206004820152601560248201527f4d757374206265206c657373207468616e2031303000000000000000000000006044820152606401620000a6565b82516060810151602090910151606491620001fc91620007f0565b60ff1611156200024f5760405162461bcd60e51b815260206004820152601d60248201527f4d6178696d756d20736c617368696e67206578636565647320313030250000006044820152606401620000a6565b82518051600f805460208085015160408087015160609788015160ff9081166401000000000260ff60201b1961ffff90931662010000029290921664ffffff0000199482166101000261ffff199097169882169890981795909517929092169590951717835580880151805160109081559181015160115593840151601280549190931660ff19919091161790915592820151869391929190601390620002f7908262000724565b50608091909101516004909101805460ff1990811660ff938416179091556040939093015151600692909201805490931691161790555062000822915050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171562000372576200037262000337565b60405290565b604051606081016001600160401b038111828210171562000372576200037262000337565b604051608081016001600160401b038111828210171562000372576200037262000337565b604051601f8201601f191681016001600160401b0381118282101715620003ed57620003ed62000337565b604052919050565b805160ff811681146200040757600080fd5b919050565b600060a082840312156200041f57600080fd5b620004296200034d565b905081518152602080830151818301526200044760408401620003f5565b604083015260608301516001600160401b03808211156200046757600080fd5b818501915085601f8301126200047c57600080fd5b81518181111562000491576200049162000337565b620004a5601f8201601f19168501620003c2565b91508082528684828501011115620004bc57600080fd5b60005b81811015620004dc578381018501518382018601528401620004bf565b50600084828401015250806060850152505050620004fd60808301620003f5565b608082015292915050565b6000602082840312156200051b57600080fd5b604051602081016001600160401b038111828210171562000540576200054062000337565b6040529050806200055183620003f5565b905292915050565b80516001600160a01b03811681146200040757600080fd5b6000806000606084860312156200058757600080fd5b83516001600160401b03808211156200059f57600080fd5b9085019081870360c0811215620005b557600080fd5b620005bf62000378565b6080821215620005ce57600080fd5b620005d86200039d565b9150620005e584620003f5565b8252620005f560208501620003f5565b6020830152604084015161ffff811681146200061057600080fd5b60408301526200062360608501620003f5565b6060830152908152608083015190828211156200063f57600080fd5b6200064d898386016200040c565b6020820152620006618960a0860162000508565b604082015295506200067a925050506020850162000559565b91506200068a6040850162000559565b90509250925092565b600181811c90821680620006a857607f821691505b602082108103620006c957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200071f576000816000526020600020601f850160051c81016020861015620006fa5750805b601f850160051c820191505b818110156200071b5782815560010162000706565b5050505b505050565b81516001600160401b0381111562000740576200074062000337565b620007588162000751845462000693565b84620006cf565b602080601f831160018114620007905760008415620007775750858301515b600019600386901b1c1916600185901b1785556200071b565b600085815260208120601f198616915b82811015620007c157888601518255948401946001909101908401620007a0565b5085821015620007e05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60ff81811683821602908116908181146200081b57634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a051613cd2620008796000396000818161044201528181611ae30152818161238e0152818161242d015281816125bb0152818161265a0152612852015260008181612d810152612f470152613cd26000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80636e2b54ee116100ee578063be5cdc4811610097578063e8aa0a0711610071578063e8aa0a07146103ed578063f752196b14610400578063fb1e61ca14610420578063fc0c546a1461044057600080fd5b8063be5cdc48146103a7578063c0cc4add146103c7578063c5d43351146103da57600080fd5b8063a3a0807e116100c8578063a3a0807e14610361578063a6af384b14610374578063b396dc791461038757600080fd5b80636e2b54ee146103335780639777b72c14610346578063a29c29a41461034e57600080fd5b80634641dce61161015b5780635da73835116101355780635da73835146102b257806362d48e13146102c75780636b00c8cf146102da5780636c70bee91461031e57600080fd5b80634641dce6146102575780634802f44b1461027c57806359cc89ed1461029f57600080fd5b80630aefaabe1161018c5780630aefaabe1461020e578063329b5a0b14610221578063458d2bf11461024457600080fd5b806302fa8e65146101b357806305b90773146101d957806308695fcd146101f9575b600080fd5b6101c66101c136600461312e565b610466565b6040519081526020015b60405180910390f35b6101ec6101e736600461312e565b6104dd565b6040516101d0919061315d565b61020c610207366004613177565b6105ef565b005b61020c61021c3660046131ae565b610745565b6101c661022f36600461312e565b60009081526017602052604090206005015490565b6101c661025236600461312e565b610922565b61026a61026536600461312e565b61093b565b60405160ff90911681526020016101d0565b61028f61028a366004613177565b61094e565b60405190151581526020016101d0565b61020c6102ad366004613203565b6109d7565b6102ba610d3e565b6040516101d0919061323a565b61020c6102d5366004613177565b610d65565b6103066102e836600461312e565b6000908152601860205260409020600501546001600160a01b031690565b6040516001600160a01b0390911681526020016101d0565b610326610e62565b6040516101d091906132c4565b61020c61034136600461312e565b611016565b6102ba611023565b61020c61035c36600461312e565b611042565b61028f61036f36600461312e565b6110b2565b61020c61038236600461336d565b6110e7565b61039a61039536600461312e565b61143c565b6040516101d09190613476565b6103ba6103b536600461312e565b611625565b6040516101d091906134a8565b61028f6103d536600461312e565b6116f3565b61020c6103e83660046134bc565b611706565b61020c6103fb3660046134ec565b611b6b565b6101c661040e36600461312e565b6000908152600a602052604090205490565b61043361042e36600461312e565b611ca0565b6040516101d0919061351a565b7f0000000000000000000000000000000000000000000000000000000000000000610306565b60008181526017602052604081206004015481610482846104dd565b9050600081600481111561049857610498613147565b14806104b5575060018160048111156104b3576104b3613147565b145b156104c1575092915050565b6104d5826104d0600142613543565b611e57565b949350505050565b60008181526016602052604081205482906001600160a01b031661053a5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b60448201526064015b60405180910390fd5b600083815260176020526040812090815460ff16600481111561055f5761055f613147565b14801561057c575060008481526017602052604090206005015442115b1561058b5760029250506105e9565b6001815460ff1660048111156105a3576105a3613147565b14806105c457506000815460ff1660048111156105c2576105c2613147565b145b80156105d35750806004015442115b156105e25760039250506105e9565b5460ff1691505b50919050565b60016105fa83611625565b600581111561060b5761060b613147565b146106585760405162461bcd60e51b815260206004820152601960248201527f536c6f74206e6f7420616363657074696e672070726f6f6673000000000000006044820152606401610531565b6106628282611e6f565b6000828152601860209081526040808320600181015484526016909252909120600f5461ffff62010000909104166106a6856000908152600a602052604090205490565b6106b0919061356c565b60000361073f57600f5460068201546000916064916106da91640100000000900460ff1690613580565b6106e49190613597565b9050808360040160008282546106fa9190613543565b9091555050600f546000868152600a6020526040902054610100820460ff169162010000900461ffff169061072f9190613597565b1061073d5761073d8561209c565b505b50505050565b826000808281526018602052604090205460ff16600581111561076a5761076a613147565b036107a65760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b6044820152606401610531565b600084815260186020526040902060058101546001600160a01b031633146108105760405162461bcd60e51b815260206004820152601960248201527f536c6f742066696c6c6564206279206f7468657220686f7374000000000000006044820152606401610531565b600061081b86611625565b9050600481600581111561083157610831613147565b0361087e5760405162461bcd60e51b815260206004820152600c60248201527f416c7265616479207061696400000000000000000000000000000000000000006044820152606401610531565b600281600581111561089257610892613147565b036108ac576108a7826001015487878761226a565b61091a565b60058160058111156108c0576108c0613147565b036108d5576108a782600101548787876124b2565b60038160058111156108e9576108e9613147565b036108f8576108a733876126dd565b600181600581111561090c5761090c613147565b0361091a5761091a8661209c565b505050505050565b6000610935826109306126ff565b61270a565b92915050565b6000610935826109496126ff565b61271e565b60408051602080820185905281830184905282518083038401815260609092019092528051910120600090339061098481612792565b80156109ad5750600154600082815260208190526040902060ff909116906109ab906127bf565b105b80156109ce575060008181526020819052604090206109cc90836127c9565b155b95945050505050565b60008381526016602052604090205483906001600160a01b0316610a2f5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b6044820152606401610531565b6000848152601660205260409020600181015467ffffffffffffffff168410610a9a5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c696420736c6f7400000000000000000000000000000000000000006044820152606401610531565b60408051602080820188905281830187905282518083038401815260609092018352815191810191909120600081815291829052919020610adb90336127c9565b610b275760405162461bcd60e51b815260206004820152601460248201527f5265736572766174696f6e2072657175697265640000000000000000000000006044820152606401610531565b6000818152601860209081526040808320600181018a905560038101899055898452601790925282209091610b5b84611625565b6005811115610b6c57610b6c613147565b14610bb95760405162461bcd60e51b815260206004820152601060248201527f536c6f74206973206e6f742066726565000000000000000000000000000000006044820152606401610531565b600484015460008481526008602090815260408083204290556009909152902055610be48387611b6b565b60058201805473ffffffffffffffffffffffffffffffffffffffff191633179055815460ff1916600190811783554260028401558181018054600090610c2b9084906135ab565b92505081905550610c408883600201546127eb565b816002016000828254610c539190613543565b90915550506006840154610c67338261280a565b8060196000016000828254610c7c91906135ab565b9091555050600483018190556005830154610ca0906001600160a01b03168561290d565b887ff530852268993f91008f1a1e0b09b5c813acd4188481f1fa83c33c7182e814b489604051610cd291815260200190565b60405180910390a26001808601549083015467ffffffffffffffff9091169003610d3357815460ff1916600117825542600383015560405189907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b505050505050505050565b336000908152600e60205260409020606090610d6090610d5d9061292f565b90565b905090565b610d6f828261094e565b610dbb5760405162461bcd60e51b815260206004820152601760248201527f5265736572766174696f6e206e6f7420616c6c6f7765640000000000000000006044820152606401610531565b60408051602080820185905281830184905282518083038401815260609092018352815191810191909120600081815291829052919020610dfc903361293c565b50600154600082815260208190526040902060ff90911690610e1d906127bf565b03610e5d57827f3bef2ebab8cc92e0edda5decf18232f0606a18405ef674b51ea9d1e0e3839b4183604051610e5491815260200190565b60405180910390a25b505050565b610ed66040805160e081019091526000606082018181526080830182905260a0830182905260c0830191909152819081526040805160a08101825260008082526020828101829052928201819052606080830152608082015291019081526040805160208181019092526000815291015290565b6040805160e081018252600f805460ff808216606080860191825261010084048316608087015261ffff6201000085041660a080880191909152640100000000909404831660c087015290855285519283018652601080548452601154602085810191909152601254909316968401969096526013805495969495928701949291840191610f63906135be565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8f906135be565b8015610fdc5780601f10610fb157610100808354040283529160200191610fdc565b820191906000526020600020905b815481529060010190602001808311610fbf57829003601f168201915b50505091835250506004919091015460ff908116602092830152918352604080518083019091526006949094015490911683520152919050565b6110208133611706565b50565b336000908152600d60205260409020606090610d6090610d5d9061292f565b806000808281526018602052604090205460ff16600581111561106757611067613147565b036110a35760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b6044820152606401610531565b6110ae823333610745565b5050565b60008060006110c8846110c36126ff565b612951565b90925090508180156104d5575060045460ff9081169116109392505050565b336110f560208301836135f2565b6001600160a01b03161461114b5760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e742061646472657373000000000000000000006044820152606401610531565b600061115e61115983613784565b612a34565b6000818152601660205260409020549091506001600160a01b0316156111c65760405162461bcd60e51b815260206004820152601660248201527f5265717565737420616c726561647920657869737473000000000000000000006044820152606401610531565b60008261012001351180156111e357506060820135610120830135105b61122f5760405162461bcd60e51b815260206004820152601360248201527f457870697279206e6f7420696e2072616e6765000000000000000000000000006044820152606401610531565b60006112416040840160208501613873565b67ffffffffffffffff16116112985760405162461bcd60e51b815260206004820152601260248201527f496e73756666696369656e7420736c6f747300000000000000000000000000006044820152606401610531565b6112a86040830160208401613873565b67ffffffffffffffff166112c3610100840160e08501613873565b67ffffffffffffffff16111561131b5760405162461bcd60e51b815260206004820152601960248201527f6d6178536c6f744c6f7373206578636565647320736c6f7473000000000000006044820152606401610531565b6000818152601660205260409020829061133582826139fe565b5061134690506060830135426135ab565b600082815260176020526040902060040155611367610120830135426135ab565b6000828152601760209081526040909120600501919091556113959061138f908401846135f2565b82612a64565b60006113a86113a384613784565b612a86565b60008381526017602052604081206002018290556019805492935083929091906113d39084906135ab565b909155506113e39050338261280a565b7f5fdb86c365a247a4d97dcbcc5c3abde9d6e3e2de26273f3fda8eef5073b9a96c8284602001601760008681526020019081526020016000206005015460405161142f93929190613af6565b60405180910390a1505050565b611444613066565b816000808281526018602052604090205460ff16600581111561146957611469613147565b036114a55760405162461bcd60e51b815260206004820152600c60248201526b536c6f74206973206672656560a01b6044820152606401610531565b60008381526018602052604090206114bb613066565b600180830154600090815260166020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186529583015467ffffffffffffffff9081168752600284015487860152600384015487870152600484015460608801526005840154608088015260068401549187019190915260078301541660c0860152918201939093528151808301835260088401805492949385019282908290611567906135be565b80601f0160208091040260200160405190810160405280929190818152602001828054611593906135be565b80156115e05780601f106115b5576101008083540402835291602001916115e0565b820191906000526020600020905b8154815290600101906020018083116115c357829003601f168201915b505050918352505060019190910154602091820152908252600a83015482820152600b9092015460409091015290825260039092015491810191909152915050919050565b6000818152601860205260408120600181015482036116475750600092915050565b600061165682600101546104dd565b90506004825460ff16600581111561167057611670613147565b0361167f575060049392505050565b600281600481111561169357611693613147565b036116a2575060059392505050565b60038160048111156116b6576116b6613147565b036116c5575060029392505050565b60048160048111156116d9576116d9613147565b036116e8575060039392505050565b505460ff1692915050565b6000610935826117016126ff565b612ab7565b600082815260166020526040902080546001600160a01b0316331461176d5760405162461bcd60e51b815260206004820152601660248201527f496e76616c696420636c69656e742061646472657373000000000000000000006044820152606401610531565b600083815260176020526040812090611785856104dd565b9050600281600481111561179b5761179b613147565b14806117b8575060048160048111156117b6576117b6613147565b145b806117d4575060038160048111156117d2576117d2613147565b145b6118205760405162461bcd60e51b815260206004820152600d60248201527f496e76616c6964207374617465000000000000000000000000000000000000006044820152606401610531565b81600201546000036118745760405162461bcd60e51b815260206004820152601360248201527f4e6f7468696e6720746f207769746864726177000000000000000000000000006044820152606401610531565b600281600481111561188857611888613147565b0361191257815460ff1916600217825560405185907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a26118e5856118e08760009081526017602052604090206005015490565b6127eb565b82600101546118f49190613580565b82600201600082825461190791906135ab565b90915550611a899050565b600481600481111561192657611926613147565b03611a7d576040805160a0808201835285546001600160a01b03168252825160e081018452600187015467ffffffffffffffff90811682526002880154602083810191909152600389015483870152600489015460608401526005890154608084015260068901549383019390935260078801541660c08201529082015281518083018352600886018054611a73948893908501929091829082906119ca906135be565b80601f01602080910402602001604051908101604052809291908181526020018280546119f6906135be565b8015611a435780601f10611a1857610100808354040283529160200191611a43565b820191906000526020600020905b815481529060010190602001808311611a2657829003601f168201915b505050505081526020016001820154815250508152602001600a8201548152602001600b82015481525050612a86565b6002830155611a89565b815460ff191660031782555b8254611a9e906001600160a01b031686612ae7565b6002820154601a8054829190600090611ab89084906135ab565b909155505060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015611b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b509190613b72565b611b5c57611b5c613b94565b50506000600290910155505050565b6000828152601860209081526040808320600101548084526016909252909120546001600160a01b0316611bd35760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b6044820152606401610531565b600083815260186020908152604080832060018101548452601683528184208251600380825260808201909452919490939092908201606080368337019050509050611c26611c2187610922565b612b09565b81600081518110611c3957611c39613baa565b60209081029190910101526009820154611c5290612b1a565b81600181518110611c6557611c65613baa565b602002602001018181525050826003015481600281518110611c8957611c89613baa565b60200260200101818152505061091a868683612b26565b611ca8613086565b60008281526016602052604090205482906001600160a01b0316611d005760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b6044820152606401610531565b600083815260166020908152604091829020825160a0808201855282546001600160a01b03168252845160e081018652600184015467ffffffffffffffff90811682526002850154828701526003850154828801526004850154606083015260058501546080830152600685015492820192909252600784015490911660c08201529281019290925282518084018452600882018054939492939285019282908290611dab906135be565b80601f0160208091040260200160405190810160405280929190818152602001828054611dd7906135be565b8015611e245780601f10611df957610100808354040283529160200191611e24565b820191906000526020600020905b815481529060010190602001808311611e0757829003601f168201915b505050505081526020016001820154815250508152602001600a8201548152602001600b82015481525050915050919050565b6000818310611e665781611e68565b825b9392505050565b6000611e7a82612ce5565b9050428110611ecb5760405162461bcd60e51b815260206004820152601860248201527f506572696f6420686173206e6f7420656e6465642079657400000000000000006044820152606401610531565b600354611ed890826135ab565b4210611f265760405162461bcd60e51b815260206004820152601460248201527f56616c69646174696f6e2074696d6564206f75740000000000000000000000006044820152606401610531565b6000838152600b6020908152604080832085845290915290205460ff1615611f905760405162461bcd60e51b815260206004820181905260248201527f50726f6f6620776173207375626d69747465642c206e6f74206d697373696e676044820152606401610531565b611f9a8383612ab7565b611fe65760405162461bcd60e51b815260206004820152601660248201527f50726f6f6620776173206e6f74207265717569726564000000000000000000006044820152606401610531565b6000838152600c6020908152604080832085845290915290205460ff16156120505760405162461bcd60e51b815260206004820152601f60248201527f50726f6f6620616c7265616479206d61726b6564206173206d697373696e67006044820152606401610531565b6000838152600c602090815260408083208584528252808320805460ff19166001908117909155868452600a90925282208054919290916120929084906135ab565b9091555050505050565b600081815260186020908152604080832060018101548085526017909352922060028301546120cc9083906127eb565b8160020160008282546120df91906135ab565b909155505060058301546120fc906001600160a01b0316856126dd565b6003808401546000868152601860205260408120805460ff1916815560018082018390556002820183905593810182905560048101829055600501805473ffffffffffffffffffffffffffffffffffffffff191690558383018054929392909190612168908490613543565b909155505060405181815283907f1d31c9f8dea6e179f6a050db117595feea8937029ea51f5168a4780be7e8f5529060200160405180910390a26000858152600a60205260408120556000838152601660205260408120600180850154908201549192916121e0919067ffffffffffffffff16613543565b600783015490915067ffffffffffffffff168111801561221557506001845460ff16600481111561221357612213613147565b145b1561226157835460ff19166004178455612230600142613543565b600485015560405185907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a25b50505050505050565b60008481526016602052604090205484906001600160a01b03166122c25760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b6044820152606401610531565b600085815260176020908152604080832060168352818420815460ff19166003178255888552601890935292208154612304906001600160a01b031689612ae7565b600581015461231c906001600160a01b0316886126dd565b600061232c8983600201546127eb565b600483015490915061233e81836135ab565b601a80546000906123509084906135ab565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156123d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fb9190613b72565b61240757612407613b94565b60405163a9059cbb60e01b81526001600160a01b038881166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249a9190613b72565b6124a6576124a6613b94565b50505050505050505050565b60008481526016602052604090205484906001600160a01b031661250a5760405162461bcd60e51b815260206004820152600f60248201526e155b9adb9bdddb881c995c5d595cdd608a1b6044820152606401610531565b60008481526018602052604090206005810154612530906001600160a01b0316866126dd565b60006125598783600201546125548a60009081526017602052604090206005015490565b612cf8565b600483015490915061256b81836135ab565b601a805460009061257d9084906135ab565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612604573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126289190613b72565b61263457612634613b94565b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156126a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c79190613b72565b6126d3576126d3613b94565b5050505050505050565b6001600160a01b0382166000908152600e60205260409020610e5d9082612d6e565b6000610d6042612d7a565b6000611e68612719848461271e565b612da6565b60008061272d6101004361356c565b600654909150600090610100906127479060ff1686613580565b612751919061356c565b905060006127616101008761356c565b905060006101008261277385876135ab565b61277d91906135ab565b612787919061356c565b979650505050505050565b60008060008381526018602052604090205460ff1660058111156127b8576127b8613147565b1492915050565b6000610935825490565b6001600160a01b03811660009081526001830160205260408120541515611e68565b600082815260176020526040812060040154611e689084908490612cf8565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd906064016020604051808303816000875af115801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190613b72565b610e5d5760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c656400000000000000000000000000000000006044820152606401610531565b6001600160a01b0382166000908152600e60205260409020610e5d9082612e00565b60606000611e6883612e0c565b6000611e68836001600160a01b038416612e68565b600080600061295f85611625565b6000868152600860205260408120549192509061297b90612d7a565b9050600182600581111561299157612991613147565b1415806129a557506129a38582612eb7565b155b156129b857600080935093505050612a2d565b6129c2868661271e565b925060006129cf84612da6565b600454909150600090610100906129e99060ff1682613bc0565b60008a815260096020526040902054612a069161ffff1690613580565b612a109190613597565b9050801580612a265750612a24818361356c565b155b9550505050505b9250929050565b600081604051602001612a47919061351a565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0382166000908152600d60205260409020610e5d9082612e00565b6020810151608081015160408201519151600092612aad9167ffffffffffffffff16613580565b6109359190613580565b6000806000612ac68585612951565b90925090508180156109ce575060045460ff90811691161015949350505050565b6001600160a01b0382166000908152600d60205260409020610e5d9082612d6e565b600060ff198216816104d582612ec1565b600080611e6883612ec1565b6000838152600b6020526040812090612b3d6126ff565b815260208101919091526040016000205460ff1615612b9e5760405162461bcd60e51b815260206004820152601760248201527f50726f6f6620616c7265616479207375626d69747465640000000000000000006044820152606401610531565b6007546040517f94c8919d0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906394c8919d90612be99085908590600401613bdb565b602060405180830381865afa158015612c06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2a9190613b72565b612c765760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642070726f6f66000000000000000000000000000000000000006044820152606401610531565b6000838152600b60205260408120600191612c8f6126ff565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f3b989d183b84b02259d7c14b34a9c9eb0fccb4c355a920d25e581e25aef4993d8360405161142f91815260200190565b6000610935612cf383612f33565b612f40565b6000838152601660205260408120828410612d555760405162461bcd60e51b815260206004820152601760248201527f5374617274206e6f74206265666f7265206578706972790000000000000000006044820152606401610531565b6005810154612d648585613543565b6109ce9190613580565b6000611e688383612f6c565b60006109357f000000000000000000000000000000000000000000000000000000000000000083613597565b60008060ff8316612db8600143613543565b612dc29190613543565b4090506000819003612dd657612dd6613b94565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b6000611e688383612e68565b606081600001805480602002602001604051908101604052809291908181526020018280548015612e5c57602002820191906000526020600020905b815481526020019060010190808311612e48575b50505050509050919050565b6000818152600183016020526040812054612eaf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610935565b506000610935565b6000818311611e68565b7fff00000000000000000000000000000000000000000000000000000000000000811660015b60208110156105e957600891821c91612f01908290613580565b83901b7fff00000000000000000000000000000000000000000000000000000000000000169190911790600101612ee7565b60006109358260016135ab565b60006109357f000000000000000000000000000000000000000000000000000000000000000083613580565b60008181526001830160205260408120548015613055576000612f90600183613543565b8554909150600090612fa490600190613543565b9050818114613009576000866000018281548110612fc457612fc4613baa565b9060005260206000200154905080876000018481548110612fe757612fe7613baa565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061301a5761301a613c86565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610935565b6000915050610935565b5092915050565b6040518060400160405280613079613086565b8152602001600081525090565b6040518060a0016040528060006001600160a01b031681526020016130f56040518060e00160405280600067ffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600067ffffffffffffffff1681525090565b815260200161311a604051806040016040528060608152602001600080191681525090565b815260006020820181905260409091015290565b60006020828403121561314057600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b602081016005831061317157613171613147565b91905290565b6000806040838503121561318a57600080fd5b50508035926020909101359150565b6001600160a01b038116811461102057600080fd5b6000806000606084860312156131c357600080fd5b8335925060208401356131d581613199565b915060408401356131e581613199565b809150509250925092565b600061010082840312156105e957600080fd5b6000806000610140848603121561321957600080fd5b833592506020840135915061323185604086016131f0565b90509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561327257835183529284019291840191600101613256565b50909695505050505050565b6000815180845260005b818110156132a457602081850181015186830182015201613288565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000825160ff815116602084015260ff602082015116604084015261ffff604082015116606084015260ff606082015116608084015250602083015160c060a0840152805160e0840152602081015161010084015260ff604082015116610120840152606081015160a061014085015261334661018085018261327e565b905060ff608083015116610160850152604085015191506104d560c08501835160ff169052565b60006020828403121561337f57600080fd5b813567ffffffffffffffff81111561339657600080fd5b82016101608185031215611e6857600080fd5b60008151604084526133be604085018261327e565b602093840151949093019390935250919050565b60006101606001600160a01b038351168452602083015167ffffffffffffffff808251166020870152602082015160408701526040820151606087015260608201516080870152608082015160a087015260a082015160c08701528060c08301511660e08701525050604083015181610100860152613453828601826133a9565b915050606083015161012085015260808301516101408501528091505092915050565b60208152600082516040602084015261349260608401826133d2565b9050602084015160408401528091505092915050565b602081016006831061317157613171613147565b600080604083850312156134cf57600080fd5b8235915060208301356134e181613199565b809150509250929050565b600080610120838503121561350057600080fd5b8235915061351184602085016131f0565b90509250929050565b602081526000611e6860208301846133d2565b634e487b7160e01b600052601160045260246000fd5b818103818111156109355761093561352d565b634e487b7160e01b600052601260045260246000fd5b60008261357b5761357b613556565b500690565b80820281158282048414176109355761093561352d565b6000826135a6576135a6613556565b500490565b808201808211156109355761093561352d565b600181811c908216806135d257607f821691505b6020821081036105e957634e487b7160e01b600052602260045260246000fd5b60006020828403121561360457600080fd5b8135611e6881613199565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156136485761364861360f565b60405290565b60405160a0810167ffffffffffffffff811182821017156136485761364861360f565b60405160e0810167ffffffffffffffff811182821017156136485761364861360f565b604051601f8201601f1916810167ffffffffffffffff811182821017156136bd576136bd61360f565b604052919050565b67ffffffffffffffff8116811461102057600080fd5b6000604082840312156136ed57600080fd5b6136f5613625565b9050813567ffffffffffffffff8082111561370f57600080fd5b818401915084601f83011261372357600080fd5b81356020828211156137375761373761360f565b613749601f8301601f19168201613694565b9250818352868183860101111561375f57600080fd5b8181850182850137600081838501015282855280860135818601525050505092915050565b600081360361016081121561379857600080fd5b6137a061364e565b83356137ab81613199565b815260e0601f19830112156137bf57600080fd5b6137c7613671565b915060208401356137d7816136c5565b8083525060408401356020830152606084013560408301526080840135606083015260a0840135608083015260c084013560a083015260e084013561381b816136c5565b60c083015260208101919091526101008301359067ffffffffffffffff82111561384457600080fd5b613850368386016136db565b604082015261012084013560608201526101409093013560808401525090919050565b60006020828403121561388557600080fd5b8135611e68816136c5565b60008135610935816136c5565b60008235603e198336030181126138b357600080fd5b9190910192915050565b601f821115610e5d576000816000526020600020601f850160051c810160208610156138e65750805b601f850160051c820191505b8181101561091a578281556001016138f2565b8135601e1983360301811261391957600080fd5b8201803567ffffffffffffffff81111561393257600080fd5b6020813603818401131561394557600080fd5b6139598261395386546135be565b866138bd565b6000601f83116001811461398f576000841561397757508482018301355b600019600386901b1c1916600185901b1786556139ec565b600086815260209020601f19851690835b828110156139c15787850186013582559385019360019091019085016139a0565b50858210156139e05760001960f88760031b161c198585890101351681555b505060018460011b0186555b50508085013560018501555050505050565b8135613a0981613199565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff19835416178255506020820135613a3e816136c5565b60018201805467ffffffffffffffff191667ffffffffffffffff83161790555060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155613ac2613a9f60e08401613890565b6007830167ffffffffffffffff821667ffffffffffffffff198254161781555050565b613adc613ad361010084018461389d565b60088301613905565b610120820135600a820155610140820135600b8201555050565b83815261012081018335613b09816136c5565b67ffffffffffffffff8082166020850152602086013560408501526040860135606085015260608601356080850152608086013560a085015260a086013560c085015260c08601359150613b5c826136c5565b1660e08301526101009091019190915292915050565b600060208284031215613b8457600080fd5b81518015158114611e6857600080fd5b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b61ffff82811682821603908082111561305f5761305f61352d565b82358152602080840135908201526000610120828101613c0b604085016040880180358252602090810135910152565b613c25608085016080880180358252602090810135910152565b613c3f60c0850160c0880180358252602090810135910152565b61010084019190915283519081905261014083019060209081860160005b82811015613c7957815185529383019390830190600101613c5d565b5092979650505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d51f0a13fcc86747a937b88d1b542ea77730e54117326a0d7340949f3dd1879864736f6c63430008170033",