chore: rebase and update

This commit is contained in:
Adam Uhlíř 2025-01-02 11:07:58 +01:00
parent 6e9c1a7cb8
commit 73b1b6cfc4
No known key found for this signature in database
GPG Key ID: 1D17A9E81F76155B
4 changed files with 46 additions and 95 deletions

View File

@ -10,7 +10,7 @@ insert_final_newline = true
# Matches multiple files with brace expansion notation # Matches multiple files with brace expansion notation
# Set default charset # Set default charset
[{*.js, *.sol}] [{*.js,*.sol}]
charset = utf-8 charset = utf-8
indent_style = space indent_style = space
indent_size = 2 indent_size = 2

View File

@ -18,6 +18,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
error Marketplace_MaximumSlashingTooHigh(); error Marketplace_MaximumSlashingTooHigh();
error Marketplace_InvalidExpiry(); error Marketplace_InvalidExpiry();
error Marketplace_InvalidMaxSlotLoss(); error Marketplace_InvalidMaxSlotLoss();
error Marketplace_InsufficientSlots();
error Marketplace_InvalidClientAddress(); error Marketplace_InvalidClientAddress();
error Marketplace_RequestAlreadyExists(); error Marketplace_RequestAlreadyExists();
error Marketplace_InvalidSlot(); error Marketplace_InvalidSlot();
@ -26,11 +27,12 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
error Marketplace_AlreadyPaid(); error Marketplace_AlreadyPaid();
error Marketplace_TransferFailed(); error Marketplace_TransferFailed();
error Marketplace_UnknownRequest(); error Marketplace_UnknownRequest();
error Marketplace_RequestNotYetTimedOut();
error Marketplace_InvalidState(); error Marketplace_InvalidState();
error Marketplace_StartNotBeforeExpiry(); error Marketplace_StartNotBeforeExpiry();
error Marketplace_SlotNotAcceptingProofs(); error Marketplace_SlotNotAcceptingProofs();
error Marketplace_SlotIsFree(); error Marketplace_SlotIsFree();
error Marketplace_ReservationRequired();
error Marketplace_NothingToWithdraw();
using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableSet for EnumerableSet.Bytes32Set;
using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.AddressSet;
@ -85,22 +87,17 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
IERC20 token_, IERC20 token_,
IGroth16Verifier verifier IGroth16Verifier verifier
) )
SlotReservations(configuration.reservations) SlotReservations(configuration.reservations)
Proofs(configuration.proofs, verifier) Proofs(configuration.proofs, verifier)
{ {
_token = token_; _token = token_;
if (configuration.collateral.repairRewardPercentage > 100) { if (configuration.collateral.repairRewardPercentage > 100) revert Marketplace_RepairRewardPercentageTooHigh();
revert Marketplace_RepairRewardPercentageTooHigh(); if (configuration.collateral.slashPercentage > 100) revert Marketplace_SlashPercentageTooHigh();
}
if (configuration.collateral.slashPercentage > 100) {
revert Marketplace_SlashPercentageTooHigh();
}
if ( if (
configuration.collateral.maxNumberOfSlashes * configuration.collateral.maxNumberOfSlashes *
configuration.collateral.slashPercentage > configuration.collateral.slashPercentage >
100 100
) { ) {
revert Marketplace_MaximumSlashingTooHigh(); revert Marketplace_MaximumSlashingTooHigh();
@ -117,21 +114,13 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
} }
function requestStorage(Request calldata request) public { function requestStorage(Request calldata request) public {
if (request.client != msg.sender) {
revert Marketplace_InvalidClientAddress();
}
RequestId id = request.id(); RequestId id = request.id();
if (_requests[id].client != address(0)) {
revert Marketplace_RequestAlreadyExists(); if (request.client != msg.sender) revert Marketplace_InvalidClientAddress();
} if (_requests[id].client != address(0)) revert Marketplace_RequestAlreadyExists();
if (request.expiry == 0 || request.expiry >= request.ask.duration) { if (request.expiry == 0 || request.expiry >= request.ask.duration) revert Marketplace_InvalidExpiry();
revert Marketplace_InvalidExpiry(); if (request.ask.slots == 0) revert Marketplace_InsufficientSlots();
} if (request.ask.maxSlotLoss > request.ask.slots) revert Marketplace_InvalidMaxSlotLoss();
// TODO: require(request.ask.slots > 0, "Insufficient slots");
if (request.ask.maxSlotLoss > request.ask.slots) {
revert Marketplace_InvalidMaxSlotLoss();
}
_requests[id] = request; _requests[id] = request;
_requestContexts[id].endsAt = block.timestamp + request.ask.duration; _requestContexts[id].endsAt = block.timestamp + request.ask.duration;
@ -161,12 +150,11 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
Groth16Proof calldata proof Groth16Proof calldata proof
) public requestIsKnown(requestId) { ) public requestIsKnown(requestId) {
Request storage request = _requests[requestId]; Request storage request = _requests[requestId];
if (slotIndex >= request.ask.slots) { if (slotIndex >= request.ask.slots) revert Marketplace_InvalidSlot();
revert Marketplace_InvalidSlot();
}
SlotId slotId = Requests.slotId(requestId, slotIndex); SlotId slotId = Requests.slotId(requestId, slotIndex);
require(_reservations[slotId].contains(msg.sender), "Reservation required");
if(!_reservations[slotId].contains(msg.sender)) revert Marketplace_ReservationRequired();
Slot storage slot = _slots[slotId]; Slot storage slot = _slots[slotId];
slot.requestId = requestId; slot.requestId = requestId;
@ -174,7 +162,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
RequestContext storage context = _requestContexts[requestId]; RequestContext storage context = _requestContexts[requestId];
if (slotState(slotId) != SlotState.Free && if (slotState(slotId) != SlotState.Free &&
slotState(slotId) != SlotState.Repair) { slotState(slotId) != SlotState.Repair) {
revert Marketplace_SlotNotFree(); revert Marketplace_SlotNotFree();
} }
@ -244,14 +232,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
address collateralRecipient address collateralRecipient
) public slotIsNotFree(slotId) { ) public slotIsNotFree(slotId) {
Slot storage slot = _slots[slotId]; Slot storage slot = _slots[slotId];
if (slot.host != msg.sender) { if (slot.host != msg.sender) revert Marketplace_InvalidSlotHost();
revert Marketplace_InvalidSlotHost();
}
SlotState state = slotState(slotId); SlotState state = slotState(slotId);
if (state == SlotState.Paid) { if (state == SlotState.Paid) revert Marketplace_AlreadyPaid();
revert Marketplace_AlreadyPaid();
}
if (state == SlotState.Finished) { if (state == SlotState.Finished) {
_payoutSlot(slot.requestId, slotId, rewardRecipient, collateralRecipient); _payoutSlot(slot.requestId, slotId, rewardRecipient, collateralRecipient);
@ -304,9 +288,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
} }
function markProofAsMissing(SlotId slotId, Period period) public { function markProofAsMissing(SlotId slotId, Period period) public {
if (slotState(slotId) != SlotState.Filled) { if (slotState(slotId) != SlotState.Filled) revert Marketplace_SlotNotAcceptingProofs();
revert Marketplace_SlotNotAcceptingProofs();
}
_markProofAsMissing(slotId, period); _markProofAsMissing(slotId, period);
Slot storage slot = _slots[slotId]; Slot storage slot = _slots[slotId];
@ -442,24 +424,20 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
address withdrawRecipient address withdrawRecipient
) public { ) public {
Request storage request = _requests[requestId]; Request storage request = _requests[requestId];
if (block.timestamp <= requestExpiry(requestId)) { RequestContext storage context = _requestContexts[requestId];
revert Marketplace_RequestNotYetTimedOut(); // TODO: Delete
}
if (request.client != msg.sender) { if (request.client != msg.sender) revert Marketplace_InvalidClientAddress();
revert Marketplace_InvalidClientAddress();
}
RequestState state = requestState(requestId); RequestState state = requestState(requestId);
if (state != RequestState.Cancelled && if (state != RequestState.Cancelled &&
state != RequestState.Failed && state != RequestState.Failed &&
state != RequestState.Finished) { state != RequestState.Finished) {
revert Marketplace_InvalidState(); revert Marketplace_InvalidState();
} }
// fundsToReturnToClient == 0 is used for "double-spend" protection, once the funds are withdrawn // fundsToReturnToClient == 0 is used for "double-spend" protection, once the funds are withdrawn
// then this variable is set to 0. // then this variable is set to 0.
require(context.fundsToReturnToClient != 0, "Nothing to withdraw"); if (context.fundsToReturnToClient == 0) revert Marketplace_NothingToWithdraw();
if (state == RequestState.Cancelled) { if (state == RequestState.Cancelled) {
context.state = RequestState.Cancelled; context.state = RequestState.Cancelled;
@ -500,9 +478,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
} }
modifier requestIsKnown(RequestId requestId) { modifier requestIsKnown(RequestId requestId) {
if (_requests[requestId].client == address(0)) { if (_requests[requestId].client == address(0)) revert Marketplace_UnknownRequest();
revert Marketplace_UnknownRequest();
}
_; _;
} }
@ -514,9 +490,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
} }
modifier slotIsNotFree(SlotId slotId) { modifier slotIsNotFree(SlotId slotId) {
if (_slots[slotId].state == SlotState.Free) { if (_slots[slotId].state == SlotState.Free) revert Marketplace_SlotIsFree();
revert Marketplace_SlotIsFree();
}
_; _;
} }
@ -551,10 +525,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
) private view returns (uint256) { ) private view returns (uint256) {
return return
_slotPayout( _slotPayout(
requestId, requestId,
startingTimestamp, startingTimestamp,
_requestContexts[requestId].endsAt _requestContexts[requestId].endsAt
); );
} }
/// @notice Calculates the amount that should be paid out to a host based on the specified time frame. /// @notice Calculates the amount that should be paid out to a host based on the specified time frame.
@ -564,9 +538,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
uint256 endingTimestamp uint256 endingTimestamp
) private view returns (uint256) { ) private view returns (uint256) {
Request storage request = _requests[requestId]; Request storage request = _requests[requestId];
if (startingTimestamp >= endingTimestamp) { if (startingTimestamp >= endingTimestamp) revert Marketplace_StartNotBeforeExpiry();
revert Marketplace_StartNotBeforeExpiry();
}
return (endingTimestamp - startingTimestamp) * request.ask.reward; return (endingTimestamp - startingTimestamp) * request.ask.reward;
} }
@ -616,9 +588,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
function _transferFrom(address sender, uint256 amount) internal { function _transferFrom(address sender, uint256 amount) internal {
address receiver = address(this); address receiver = address(this);
if (!_token.transferFrom(sender, receiver, amount)) { if (!_token.transferFrom(sender, receiver, amount)) revert Marketplace_TransferFailed();
revert Marketplace_TransferFailed();
}
} }
event StorageRequested(RequestId requestId, Ask ask, uint256 expiry); event StorageRequested(RequestId requestId, Ask ask, uint256 expiry);

View File

@ -201,13 +201,8 @@ abstract contract Proofs is Periods {
Groth16Proof calldata proof, Groth16Proof calldata proof,
uint[] memory pubSignals uint[] memory pubSignals
) internal { ) internal {
if (_received[id][_blockPeriod()]) { if (_received[id][_blockPeriod()]) revert Proofs_ProofAlreadySubmitted();
revert Proofs_ProofAlreadySubmitted(); if (!_verifier.verify(proof, pubSignals)) revert Proofs_InvalidProof();
}
if (!_verifier.verify(proof, pubSignals)) {
revert Proofs_InvalidProof();
}
_received[id][_blockPeriod()] = true; _received[id][_blockPeriod()] = true;
emit ProofSubmitted(id); emit ProofSubmitted(id);
@ -227,25 +222,11 @@ abstract contract Proofs is Periods {
*/ */
function _markProofAsMissing(SlotId id, Period missedPeriod) internal { function _markProofAsMissing(SlotId id, Period missedPeriod) internal {
uint256 end = _periodEnd(missedPeriod); uint256 end = _periodEnd(missedPeriod);
if (end >= block.timestamp) { if (end >= block.timestamp) revert Proofs_PeriodNotEnded();
revert Proofs_PeriodNotEnded(); if (block.timestamp >= end + _config.timeout) revert Proofs_ValidationTimedOut();
} if (_received[id][missedPeriod]) revert Proofs_ProofNotMissing();
if (!_isProofRequired(id, missedPeriod)) revert Proofs_ProofNotRequired();
if (block.timestamp >= end + _config.timeout) { if (_missing[id][missedPeriod]) revert Proofs_ProofAlreadyMarkedMissing();
revert Proofs_ValidationTimedOut();
}
if (_received[id][missedPeriod]) {
revert Proofs_ProofNotMissing();
}
if (!_isProofRequired(id, missedPeriod)) {
revert Proofs_ProofNotRequired();
}
if (_missing[id][missedPeriod]) {
revert Proofs_ProofAlreadyMarkedMissing();
}
_missing[id][missedPeriod] = true; _missing[id][missedPeriod] = true;
_missed[id] += 1; _missed[id] += 1;

View File

@ -220,7 +220,7 @@ describe("Marketplace", function () {
it("is rejected with insufficient slots ", async function () { it("is rejected with insufficient slots ", async function () {
request.ask.slots = 0 request.ask.slots = 0
await expect(marketplace.requestStorage(request)).to.be.revertedWith( await expect(marketplace.requestStorage(request)).to.be.revertedWith(
"Insufficient slots" "Marketplace_InsufficientSlots"
) )
}) })
@ -381,7 +381,7 @@ describe("Marketplace", function () {
it("fails if slot is not reserved first", async function () { it("fails if slot is not reserved first", async function () {
await expect( await expect(
marketplace.fillSlot(slot.request, slot.index, proof) marketplace.fillSlot(slot.request, slot.index, proof)
).to.be.revertedWith("Reservation required") ).to.be.revertedWith("Marketplace_ReservationRequired")
}) })
}) })
@ -824,7 +824,7 @@ describe("Marketplace", function () {
switchAccount(client) switchAccount(client)
await expect( await expect(
marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address) marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address)
).to.be.revertedWith("Marketplace_InvalidClientAddress") ).to.be.revertedWith("Marketplace_InvalidState")
}) })
it("rejects withdraw when already withdrawn", async function () { it("rejects withdraw when already withdrawn", async function () {
@ -838,7 +838,7 @@ describe("Marketplace", function () {
) )
await expect( await expect(
marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address) marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address)
).to.be.revertedWith("Nothing to withdraw") ).to.be.revertedWith("Marketplace_NothingToWithdraw")
}) })
it("emits event once request is cancelled", async function () { it("emits event once request is cancelled", async function () {