From cfb70897f8567148385144e1aafd9d0fb2e4836d Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Thu, 29 Sep 2022 20:18:02 +1000 Subject: [PATCH] [marketplace] alias bytes32 types `RequestId`, `SlotId`, `LockId`, `ProofId`, `EndId` types were created to avoid confusion and enforce compiler restrictions. --- contracts/AccountLocks.sol | 22 ++--- contracts/Marketplace.sol | 156 ++++++++++++++++++++++----------- contracts/Proofs.sol | 64 +++++++------- contracts/Storage.sol | 37 ++++---- contracts/TestAccountLocks.sol | 8 +- contracts/TestCollateral.sol | 6 +- contracts/TestMarketplace.sol | 10 +-- contracts/TestProofs.sol | 22 ++--- hardhat.config.js | 2 +- 9 files changed, 191 insertions(+), 136 deletions(-) diff --git a/contracts/AccountLocks.sol b/contracts/AccountLocks.sol index e52067a..5d438e6 100644 --- a/contracts/AccountLocks.sol +++ b/contracts/AccountLocks.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; /// Implements account locking. The main goal of this design is to allow /// unlocking of multiple accounts in O(1). To achieve this we keep a list of @@ -8,14 +8,16 @@ pragma solidity ^0.8.0; /// this operation does not become too expensive in gas costs, a maximum amount /// of active locks per account is enforced. contract AccountLocks { + type LockId is bytes32; + uint256 public constant MAX_LOCKS_PER_ACCOUNT = 128; - mapping(bytes32 => Lock) private locks; + mapping(LockId => Lock) private locks; mapping(address => Account) private accounts; /// Creates a lock that can be used to lock accounts. The id needs to be /// unique and collision resistant. The expiry time is given in unix time. - function _createLock(bytes32 id, uint256 expiry) internal { + function _createLock(LockId id, uint256 expiry) internal { require(locks[id].owner == address(0), "Lock already exists"); locks[id] = Lock(msg.sender, expiry, false); } @@ -24,9 +26,9 @@ contract AccountLocks { /// can the account be unlocked again. /// Calling this function triggers a cleanup of inactive locks, making this /// an O(N) operation, where N = MAX_LOCKS_PER_ACCOUNT. - function _lock(address account, bytes32 lockId) internal { + function _lock(address account, LockId lockId) internal { require(locks[lockId].owner != address(0), "Lock does not exist"); - bytes32[] storage accountLocks = accounts[account].locks; + LockId[] storage accountLocks = accounts[account].locks; removeInactiveLocks(accountLocks); require(accountLocks.length < MAX_LOCKS_PER_ACCOUNT, "Max locks reached"); accountLocks.push(lockId); @@ -35,7 +37,7 @@ contract AccountLocks { /// Unlocks a lock, thereby freeing any accounts that are attached to this /// lock. This is an O(1) operation. Only the party that created the lock is /// allowed to unlock it. - function _unlock(bytes32 lockId) internal { + function _unlock(LockId lockId) internal { Lock storage lock = locks[lockId]; require(lock.owner != address(0), "Lock does not exist"); require(lock.owner == msg.sender, "Only lock creator can unlock"); @@ -46,7 +48,7 @@ contract AccountLocks { /// NOTE: We do not need to check that msg.sender is the lock.owner because /// this function is internal, and is only called after all checks have been /// performed in Marketplace.fillSlot. - function _extendLockExpiryTo(bytes32 lockId, uint256 expiry) internal { + function _extendLockExpiryTo(LockId lockId, uint256 expiry) internal { Lock storage lock = locks[lockId]; require(lock.owner != address(0), "Lock does not exist"); require(lock.expiry >= block.timestamp, "Lock already expired"); @@ -58,12 +60,12 @@ contract AccountLocks { /// Calling this function triggers a cleanup of inactive locks, making this /// an O(N) operation, where N = MAX_LOCKS_PER_ACCOUNT. function _unlockAccount() internal { - bytes32[] storage accountLocks = accounts[msg.sender].locks; + LockId[] storage accountLocks = accounts[msg.sender].locks; removeInactiveLocks(accountLocks); require(accountLocks.length == 0, "Account locked"); } - function removeInactiveLocks(bytes32[] storage lockIds) private { + function removeInactiveLocks(LockId[] storage lockIds) private { uint256 index = 0; while (true) { if (index >= lockIds.length) { @@ -89,6 +91,6 @@ contract AccountLocks { } struct Account { - bytes32[] locks; + LockId[] locks; } } diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index 23a5939..169ad16 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; @@ -7,11 +7,14 @@ import "./Collateral.sol"; import "./Proofs.sol"; contract Marketplace is Collateral, Proofs { + type RequestId is bytes32; + type SlotId is bytes32; + uint256 public immutable collateral; MarketplaceFunds private funds; - mapping(bytes32 => Request) private requests; - mapping(bytes32 => RequestContext) private requestContexts; - mapping(bytes32 => Slot) private slots; + mapping(RequestId => Request) private requests; + mapping(RequestId => RequestContext) private requestContexts; + mapping(SlotId => Slot) private slots; constructor( IERC20 _token, @@ -33,17 +36,17 @@ contract Marketplace is Collateral, Proofs { { require(request.client == msg.sender, "Invalid client address"); - bytes32 id = keccak256(abi.encode(request)); + RequestId id = _toRequestId(request); require(requests[id].client == address(0), "Request already exists"); requests[id] = request; RequestContext storage context = _context(id); // set contract end time to `duration` from now (time request was created) context.endsAt = block.timestamp + request.ask.duration; - _setProofEnd(id, context.endsAt); + _setProofEnd(_toEndId(id), context.endsAt); - _createLock(id, request.expiry); + _createLock(_toLockId(id), request.expiry); uint256 amount = price(request); funds.received += amount; @@ -54,22 +57,27 @@ contract Marketplace is Collateral, Proofs { } function fillSlot( - bytes32 requestId, + RequestId requestId, uint256 slotIndex, bytes calldata proof ) public requestMustAcceptProofs(requestId) marketplaceInvariant { Request storage request = _request(requestId); require(slotIndex < request.ask.slots, "Invalid slot"); - bytes32 slotId = keccak256(abi.encode(requestId, slotIndex)); + SlotId slotId = _toSlotId(requestId, slotIndex); Slot storage slot = slots[slotId]; require(slot.host == address(0), "Slot already filled"); require(balanceOf(msg.sender) >= collateral, "Insufficient collateral"); - _lock(msg.sender, requestId); + LockId lockId = _toLockId(requestId); + _lock(msg.sender, lockId); - _expectProofs(slotId, requestId, request.ask.proofProbability); - _submitProof(slotId, proof); + ProofId proofId = _toProofId(slotId); + _expectProofs( + proofId, + requestId, + request.ask.proofProbability); + _submitProof(proofId, proof); slot.host = msg.sender; slot.requestId = requestId; @@ -79,16 +87,16 @@ contract Marketplace is Collateral, Proofs { if (context.slotsFilled == request.ask.slots) { context.state = RequestState.Started; context.startedAt = block.timestamp; - _extendLockExpiryTo(requestId, context.endsAt); + _extendLockExpiryTo(lockId, context.endsAt); emit RequestFulfilled(requestId); } } function _freeSlot( - bytes32 slotId + SlotId slotId ) internal slotMustAcceptProofs(slotId) marketplaceInvariant { Slot storage slot = _slot(slotId); - bytes32 requestId = slot.requestId; + RequestId requestId = slot.requestId; RequestContext storage context = requestContexts[requestId]; // TODO: burn host's slot collateral except for repair costs + mark proof @@ -96,10 +104,10 @@ contract Marketplace is Collateral, Proofs { // Slot collateral is not yet implemented as the design decision was // not finalised. - _unexpectProofs(slotId); + _unexpectProofs(_toProofId(slotId)); slot.host = address(0); - slot.requestId = 0; + slot.requestId = RequestId.wrap(0); context.slotsFilled -= 1; emit SlotFreed(requestId, slotId); @@ -118,16 +126,14 @@ contract Marketplace is Collateral, Proofs { // TODO: send client remaining funds } } - - function payoutSlot(bytes32 requestId, uint256 slotIndex) + function payoutSlot(RequestId requestId, uint256 slotIndex) public marketplaceInvariant { require(_isFinished(requestId), "Contract not ended"); RequestContext storage context = _context(requestId); context.state = RequestState.Finished; - - bytes32 slotId = keccak256(abi.encode(requestId, slotIndex)); + SlotId slotId = _toSlotId(requestId, slotIndex); Slot storage slot = _slot(slotId); require(!slot.hostPaid, "Already paid"); uint256 amount = pricePerSlot(requests[requestId]); @@ -140,7 +146,7 @@ contract Marketplace is Collateral, Proofs { /// @notice Withdraws storage request funds back to the client that deposited them. /// @dev Request must be expired, must be in RequestState.New, and the transaction must originate from the depositer address. /// @param requestId the id of the request - function withdrawFunds(bytes32 requestId) public marketplaceInvariant { + function withdrawFunds(RequestId requestId) public marketplaceInvariant { Request storage request = requests[requestId]; require(block.timestamp > request.expiry, "Request not yet timed out"); require(request.client == msg.sender, "Invalid client address"); @@ -165,7 +171,7 @@ contract Marketplace is Collateral, Proofs { /// @dev Handles the case when a request may have been cancelled, but the client has not withdrawn its funds yet, and therefore the state has not yet been updated. /// @param requestId the id of the request /// @return true if request is cancelled - function _isCancelled(bytes32 requestId) internal view returns (bool) { + function _isCancelled(RequestId requestId) internal view returns (bool) { RequestContext storage context = _context(requestId); return context.state == RequestState.Cancelled || @@ -179,7 +185,7 @@ contract Marketplace is Collateral, Proofs { /// @dev Handles the case when a request may have been finished, but the state has not yet been updated by a transaction. /// @param requestId the id of the request /// @return true if request is finished - function _isFinished(bytes32 requestId) internal view returns (bool) { + function _isFinished(RequestId requestId) internal view returns (bool) { RequestContext memory context = _context(requestId); return context.state == RequestState.Finished || @@ -193,9 +199,13 @@ contract Marketplace is Collateral, Proofs { /// @dev Returns requestId that is mapped to the slotId /// @param slotId id of the slot /// @return if of the request the slot belongs to - function _getRequestIdForSlot(bytes32 slotId) internal view returns (bytes32) { + function _getRequestIdForSlot(SlotId slotId) + internal + view + returns (RequestId) + { Slot memory slot = _slot(slotId); - require(slot.requestId != 0, "Missing request id"); + require(_notEqual(slot.requestId, 0), "Missing request id"); return slot.requestId; } @@ -203,28 +213,36 @@ contract Marketplace is Collateral, Proofs { /// @dev Handles the case when a request may have been cancelled, but the client has not withdrawn its funds yet, and therefore the state has not yet been updated. /// @param slotId the id of the slot /// @return true if request is cancelled - function _isSlotCancelled(bytes32 slotId) internal view returns (bool) { - bytes32 requestId = _getRequestIdForSlot(slotId); + function _isSlotCancelled(SlotId slotId) internal view returns (bool) { + RequestId requestId = _getRequestIdForSlot(slotId); return _isCancelled(requestId); } - function _host(bytes32 slotId) internal view returns (address) { + function _host(SlotId slotId) internal view returns (address) { return slots[slotId].host; } - function _request(bytes32 requestId) internal view returns (Request storage) { + function _request(RequestId requestId) + internal + view + returns (Request storage) + { Request storage request = requests[requestId]; require(request.client != address(0), "Unknown request"); return request; } - function _slot(bytes32 slotId) internal view returns (Slot storage) { + function _slot(SlotId slotId) internal view returns (Slot storage) { Slot storage slot = slots[slotId]; require(slot.host != address(0), "Slot empty"); return slot; } - function _context(bytes32 requestId) internal view returns (RequestContext storage) { + function _context(RequestId requestId) + internal + view + returns (RequestContext storage) + { return requestContexts[requestId]; } @@ -238,7 +256,7 @@ contract Marketplace is Collateral, Proofs { function proofEnd(bytes32 slotId) public view returns (uint256) { Slot memory slot = _slot(slotId); - uint256 end = _end(slot.requestId); + uint256 end = _end(_toEndId(slot.requestId)); if (_slotAcceptsProofs(slotId)) { return end; } else { @@ -266,7 +284,7 @@ contract Marketplace is Collateral, Proofs { return request.ask.duration * request.ask.reward; } - function state(bytes32 requestId) public view returns (RequestState) { + function state(RequestId requestId) public view returns (RequestState) { if (_isCancelled(requestId)) { return RequestState.Cancelled; } else if (_isFinished(requestId)) { @@ -279,20 +297,52 @@ contract Marketplace is Collateral, Proofs { /// @notice returns true when the request is accepting proof submissions from hosts occupying slots. /// @dev Request state must be new or started, and must not be cancelled, finished, or failed. - /// @param requestId id of the request for which to obtain state info - function _requestAcceptsProofs(bytes32 requestId) internal view returns (bool) { - RequestState s = state(requestId); - return s == RequestState.New || s == RequestState.Started; + /// @param slotId id of the slot, that is mapped to a request, for which to obtain state info + function _slotAcceptsProofs(SlotId slotId) internal view returns (bool) { + RequestId requestId = _getRequestIdForSlot(slotId); + return _requestAcceptsProofs(requestId); } /// @notice returns true when the request is accepting proof submissions from hosts occupying slots. /// @dev Request state must be new or started, and must not be cancelled, finished, or failed. - /// @param slotId id of the slot, that is mapped to a request, for which to obtain state info - function _slotAcceptsProofs(bytes32 slotId) internal view returns (bool) { - bytes32 requestId = _getRequestIdForSlot(slotId); - return _requestAcceptsProofs(requestId); + /// @param requestId id of the request for which to obtain state info + function _requestAcceptsProofs(RequestId requestId) internal view returns (bool) { + RequestState s = state(requestId); + return s == RequestState.New || s == RequestState.Started; } + function _toRequestId(Request memory request) + internal + pure + returns (RequestId) + { + return RequestId.wrap(keccak256(abi.encode(request))); + } + + function _toSlotId( + RequestId requestId, + uint256 slotIndex) + internal + pure + returns (SlotId) + { + return SlotId.wrap(keccak256(abi.encode(requestId, slotIndex))); + } + + function _toLockId(RequestId requestId) internal pure returns (LockId) { + return LockId.wrap(RequestId.unwrap(requestId)); + } + + function _toProofId(SlotId slotId) internal pure returns (ProofId) { + return ProofId.wrap(SlotId.unwrap(slotId)); + } + + + function _notEqual(RequestId a, uint256 b) internal pure returns (bool) { + return RequestId.unwrap(a) != bytes32(b); + } + + struct Request { address client; Ask ask; @@ -344,19 +394,19 @@ contract Marketplace is Collateral, Proofs { struct Slot { address host; bool hostPaid; - bytes32 requestId; + RequestId requestId; } - event StorageRequested(bytes32 requestId, Ask ask); - event RequestFulfilled(bytes32 indexed requestId); - event RequestFailed(bytes32 indexed requestId); + event StorageRequested(RequestId requestId, Ask ask); + event RequestFulfilled(RequestId indexed requestId); + event RequestFailed(RequestId indexed requestId); event SlotFilled( - bytes32 indexed requestId, + RequestId indexed requestId, uint256 indexed slotIndex, - bytes32 slotId + SlotId slotId ); - event SlotFreed(bytes32 indexed requestId, bytes32 slotId); - event RequestCancelled(bytes32 indexed requestId); + event SlotFreed(RequestId indexed requestId, SlotId slotId); + event RequestCancelled(RequestId indexed requestId); modifier marketplaceInvariant() { MarketplaceFunds memory oldFunds = funds; @@ -369,8 +419,8 @@ contract Marketplace is Collateral, Proofs { /// @notice Modifier that requires the request state to be that which is accepting proof submissions from hosts occupying slots. /// @dev Request state must be new or started, and must not be cancelled, finished, or failed. /// @param slotId id of the slot, that is mapped to a request, for which to obtain state info - modifier slotMustAcceptProofs(bytes32 slotId) { - bytes32 requestId = _getRequestIdForSlot(slotId); + modifier slotMustAcceptProofs(SlotId slotId) { + RequestId requestId = _getRequestIdForSlot(slotId); require(_requestAcceptsProofs(requestId), "Slot not accepting proofs"); _; } @@ -378,7 +428,7 @@ contract Marketplace is Collateral, Proofs { /// @notice Modifier that requires the request state to be that which is accepting proof submissions from hosts occupying slots. /// @dev Request state must be new or started, and must not be cancelled, finished, or failed. /// @param requestId id of the request, for which to obtain state info - modifier requestMustAcceptProofs(bytes32 requestId) { + modifier requestMustAcceptProofs(RequestId requestId) { require(_requestAcceptsProofs(requestId), "Request not accepting proofs"); _; } diff --git a/contracts/Proofs.sol b/contracts/Proofs.sol index 3210106..21e1265 100644 --- a/contracts/Proofs.sol +++ b/contracts/Proofs.sol @@ -1,7 +1,9 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; contract Proofs { + type ProofId is bytes32; + uint256 private immutable period; uint256 private immutable timeout; uint8 private immutable downtime; @@ -17,15 +19,15 @@ contract Proofs { downtime = __downtime; } - mapping(bytes32 => bool) private ids; - mapping(bytes32 => uint256) private starts; - mapping(bytes32 => uint256) private ends; - mapping(bytes32 => bytes32) private idEnds; - mapping(bytes32 => uint256) private probabilities; - mapping(bytes32 => uint256) private markers; - mapping(bytes32 => uint256) private missed; - mapping(bytes32 => mapping(uint256 => bool)) private received; - mapping(bytes32 => mapping(uint256 => bool)) private missing; + mapping(ProofId => bool) private ids; + mapping(ProofId => uint256) private starts; + mapping(EndId => uint256) private ends; + mapping(ProofId => EndId) private idEnds; + mapping(ProofId => uint256) private probabilities; + mapping(ProofId => uint256) private markers; + mapping(ProofId => uint256) private missed; + mapping(ProofId => mapping(uint256 => bool)) private received; + mapping(ProofId => mapping(uint256 => bool)) private missing; function _period() internal view returns (uint256) { return period; @@ -35,24 +37,24 @@ contract Proofs { return timeout; } - function _end(bytes32 endId) internal view returns (uint256) { + function _end(ProofId id) internal view returns (uint256) { uint256 end = ends[endId]; require(end > 0, "Proof ending doesn't exist"); return ends[endId]; } - function _endId(bytes32 id) internal view returns (bytes32) { - bytes32 endId = idEnds[id]; + function _endId(ProofId id) internal view returns (EndId) { + EndId endId = idEnds[id]; require(endId > 0, "endId for given id doesn't exist"); return endId; } - function _endFromId(bytes32 id) internal view returns (uint256) { - bytes32 endId = _endId(id); + function _endFromId(ProofId id) internal view returns (uint256) { + EndId endId = _endId(id); return _end(endId); } - function _missed(bytes32 id) internal view returns (uint256) { + function _missed(ProofId id) internal view returns (uint256) { return missed[id]; } @@ -70,8 +72,8 @@ contract Proofs { /// @param endId Identifies the id of the proof expectation ending. Typically a request id. Different from id because the proof ending is shared amongst many ids. /// @param probability The probability that a proof should be expected function _expectProofs( - bytes32 id, // typically slot id - bytes32 endId, // typically request id, used so that the ending is global for all slots + ProofId id, // typically slot id + EndId endId, // typically request id, used so that the ending is global for all slots uint256 probability ) internal { require(!ids[id], "Proof id already in use"); @@ -83,25 +85,25 @@ contract Proofs { } function _unexpectProofs( - bytes32 id + ProofId id ) internal { require(ids[id], "Proof id not in use"); ids[id] = false; } - function _getPointer(bytes32 id, uint256 proofPeriod) + function _getPointer(ProofId id, uint256 proofPeriod) internal view returns (uint8) { uint256 blockNumber = block.number % 256; uint256 periodNumber = proofPeriod % 256; - uint256 idOffset = uint256(id) % 256; + uint256 idOffset = uint256(ProofId.unwrap(id)) % 256; uint256 pointer = (blockNumber + periodNumber + idOffset) % 256; return uint8(pointer); } - function _getPointer(bytes32 id) internal view returns (uint8) { + function _getPointer(ProofId id) internal view returns (uint8) { return _getPointer(id, currentPeriod()); } @@ -111,7 +113,7 @@ contract Proofs { return keccak256(abi.encode(hash)); } - function _getChallenge(bytes32 id, uint256 proofPeriod) + function _getChallenge(ProofId id, uint256 proofPeriod) internal view returns (bytes32) @@ -119,11 +121,11 @@ contract Proofs { return _getChallenge(_getPointer(id, proofPeriod)); } - function _getChallenge(bytes32 id) internal view returns (bytes32) { + function _getChallenge(ProofId id) internal view returns (bytes32) { return _getChallenge(id, currentPeriod()); } - function _getProofRequirement(bytes32 id, uint256 proofPeriod) + function _getProofRequirement(ProofId id, uint256 proofPeriod) internal view returns (bool isRequired, uint8 pointer) @@ -141,7 +143,7 @@ contract Proofs { isRequired = ids[id] && uint256(challenge) % probability == 0; } - function _isProofRequired(bytes32 id, uint256 proofPeriod) + function _isProofRequired(ProofId id, uint256 proofPeriod) internal view returns (bool) @@ -152,25 +154,25 @@ contract Proofs { return isRequired && pointer >= downtime; } - function _isProofRequired(bytes32 id) internal view returns (bool) { + function _isProofRequired(ProofId id) internal view returns (bool) { return _isProofRequired(id, currentPeriod()); } - function _willProofBeRequired(bytes32 id) internal view returns (bool) { + function _willProofBeRequired(ProofId id) internal view returns (bool) { bool isRequired; uint8 pointer; (isRequired, pointer) = _getProofRequirement(id, currentPeriod()); return isRequired && pointer < downtime; } - function _submitProof(bytes32 id, bytes calldata proof) internal { + function _submitProof(ProofId id, bytes calldata proof) internal { require(proof.length > 0, "Invalid proof"); // TODO: replace by actual check require(!received[id][currentPeriod()], "Proof already submitted"); received[id][currentPeriod()] = true; emit ProofSubmitted(id, proof); } - function _markProofAsMissing(bytes32 id, uint256 missedPeriod) internal { + function _markProofAsMissing(ProofId id, uint256 missedPeriod) internal { uint256 periodEnd = (missedPeriod + 1) * period; require(periodEnd < block.timestamp, "Period has not ended yet"); require(block.timestamp < periodEnd + timeout, "Validation timed out"); @@ -192,5 +194,5 @@ contract Proofs { ends[endId] = ending; } - event ProofSubmitted(bytes32 id, bytes proof); + event ProofSubmitted(ProofId id, bytes proof); } diff --git a/contracts/Storage.sol b/contracts/Storage.sol index 7699c45..ed65fea 100644 --- a/contracts/Storage.sol +++ b/contracts/Storage.sol @@ -35,58 +35,59 @@ contract Storage is Collateral, Marketplace { minCollateralThreshold = _minCollateralThreshold; } - function getRequest(bytes32 requestId) public view returns (Request memory) { + function getRequest(RequestId requestId) public view returns (Request memory) { return _request(requestId); } - function getSlot(bytes32 slotId) public view returns (Slot memory) { + function getSlot(SlotId slotId) public view returns (Slot memory) { return _slot(slotId); } - function getHost(bytes32 slotId) public view returns (address) { + function getHost(SlotId slotId) public view returns (address) { return _host(slotId); } - function missingProofs(bytes32 slotId) public view returns (uint256) { - return _missed(slotId); + function missingProofs(SlotId slotId) public view returns (uint256) { + return _missed(_toProofId(slotId)); } - function isProofRequired(bytes32 slotId) public view returns (bool) { + function isProofRequired(SlotId slotId) public view returns (bool) { if(!_slotAcceptsProofs(slotId)) { return false; } - return _isProofRequired(slotId); + return _isProofRequired(_toProofId(slotId)); } - function willProofBeRequired(bytes32 slotId) public view returns (bool) { + function willProofBeRequired(SlotId slotId) public view returns (bool) { if(!_slotAcceptsProofs(slotId)) { return false; } - return _willProofBeRequired(slotId); + return _willProofBeRequired(_toProofId(slotId)); } - function getChallenge(bytes32 slotId) public view returns (bytes32) { + function getChallenge(SlotId slotId) public view returns (bytes32) { if(!_slotAcceptsProofs(slotId)) { return bytes32(0); } - return _getChallenge(slotId); + return _getChallenge(_toProofId(slotId)); } - function getPointer(bytes32 slotId) public view returns (uint8) { - return _getPointer(slotId); + function getPointer(SlotId slotId) public view returns (uint8) { + return _getPointer(_toProofId(slotId)); } - function submitProof(bytes32 slotId, bytes calldata proof) public { - _submitProof(slotId, proof); + function submitProof(SlotId slotId, bytes calldata proof) public { + _submitProof(_toProofId(slotId), proof); } - function markProofAsMissing(bytes32 slotId, uint256 period) + function markProofAsMissing(SlotId slotId, uint256 period) public slotMustAcceptProofs(slotId) { - _markProofAsMissing(slotId, period); + ProofId proofId = _toProofId(slotId); + _markProofAsMissing(proofId, period); address host = _host(slotId); - if (_missed(slotId) % slashMisses == 0) { + if (_missed(_toProofId(slotId)) % slashMisses == 0) { _slash(host, slashPercentage); if (balanceOf(host) < minCollateralThreshold) { diff --git a/contracts/TestAccountLocks.sol b/contracts/TestAccountLocks.sol index e16340b..ef76c3c 100644 --- a/contracts/TestAccountLocks.sol +++ b/contracts/TestAccountLocks.sol @@ -5,15 +5,15 @@ import "./AccountLocks.sol"; // exposes internal functions for testing contract TestAccountLocks is AccountLocks { - function createLock(bytes32 id, uint256 expiry) public { + function createLock(LockId id, uint256 expiry) public { _createLock(id, expiry); } - function lock(address account, bytes32 id) public { + function lock(address account, LockId id) public { _lock(account, id); } - function unlock(bytes32 id) public { + function unlock(LockId id) public { _unlock(id); } @@ -21,7 +21,7 @@ contract TestAccountLocks is AccountLocks { _unlockAccount(); } - function extendLockExpiryTo(bytes32 lockId, uint256 expiry) public { + function extendLockExpiryTo(LockId lockId, uint256 expiry) public { _extendLockExpiryTo(lockId, expiry); } } diff --git a/contracts/TestCollateral.sol b/contracts/TestCollateral.sol index 2524c76..25bb366 100644 --- a/contracts/TestCollateral.sol +++ b/contracts/TestCollateral.sol @@ -12,15 +12,15 @@ contract TestCollateral is Collateral { _slash(account, percentage); } - function createLock(bytes32 id, uint256 expiry) public { + function createLock(LockId id, uint256 expiry) public { _createLock(id, expiry); } - function lock(address account, bytes32 id) public { + function lock(address account, LockId id) public { _lock(account, id); } - function unlock(bytes32 id) public { + function unlock(LockId id) public { _unlock(id); } } diff --git a/contracts/TestMarketplace.sol b/contracts/TestMarketplace.sol index 62b5a30..3611db3 100644 --- a/contracts/TestMarketplace.sol +++ b/contracts/TestMarketplace.sol @@ -18,23 +18,23 @@ contract TestMarketplace is Marketplace { } - function isCancelled(bytes32 requestId) public view returns (bool) { + function isCancelled(RequestId requestId) public view returns (bool) { return _isCancelled(requestId); } - function isSlotCancelled(bytes32 slotId) public view returns (bool) { + function isSlotCancelled(SlotId slotId) public view returns (bool) { return _isSlotCancelled(slotId); } - function freeSlot(bytes32 slotId) public { + function freeSlot(SlotId slotId) public { _freeSlot(slotId); } - function slot(bytes32 slotId) public view returns (Slot memory) { + function slot(SlotId slotId) public view returns (Slot memory) { return _slot(slotId); } - function testAcceptsProofs(bytes32 slotId) + function testAcceptsProofs(SlotId slotId) public view slotMustAcceptProofs(slotId) diff --git a/contracts/TestProofs.sol b/contracts/TestProofs.sol index d9d01c3..9f5b0ff 100644 --- a/contracts/TestProofs.sol +++ b/contracts/TestProofs.sol @@ -24,47 +24,47 @@ contract TestProofs is Proofs { return _timeout(); } - function end(bytes32 id) public view returns (uint256) { + function end(ProofId id) public view returns (uint256) { return _end(id); } - function missed(bytes32 id) public view returns (uint256) { + function missed(ProofId id) public view returns (uint256) { return _missed(id); } function expectProofs( - bytes32 id, - bytes32 endId, + ProofId id, + EndId endId, uint256 _probability ) public { _expectProofs(id, endId, _probability); } - function unexpectProofs(bytes32 id) public { + function unexpectProofs(ProofId id) public { _unexpectProofs(id); } - function isProofRequired(bytes32 id) public view returns (bool) { + function isProofRequired(ProofId id) public view returns (bool) { return _isProofRequired(id); } - function willProofBeRequired(bytes32 id) public view returns (bool) { + function willProofBeRequired(ProofId id) public view returns (bool) { return _willProofBeRequired(id); } - function getChallenge(bytes32 id) public view returns (bytes32) { + function getChallenge(ProofId id) public view returns (bytes32) { return _getChallenge(id); } - function getPointer(bytes32 id) public view returns (uint8) { + function getPointer(ProofId id) public view returns (uint8) { return _getPointer(id); } - function submitProof(bytes32 id, bytes calldata proof) public { + function submitProof(ProofId id, bytes calldata proof) public { _submitProof(id, proof); } - function markProofAsMissing(bytes32 id, uint256 _period) public { + function markProofAsMissing(ProofId id, uint256 _period) public { _markProofAsMissing(id, _period); } diff --git a/hardhat.config.js b/hardhat.config.js index 2399e1f..6ee3ede 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -4,7 +4,7 @@ require("hardhat-deploy-ethers") module.exports = { solidity: { - version: "0.8.4", + version: "0.8.8", settings: { optimizer: { enabled: true,