@@ -126,7 +126,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
126
126
}
127
127
128
128
/**
129
- * @notice Fills a slot. Reverts if an invalid proof of the slot data is
129
+ * @notice Fills a slot. Reverts if an invalid proof of the slot data is
130
130
provided.
131
131
* @param requestId RequestId identifying the request containing the slot to
132
132
fill.
@@ -149,36 +149,55 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
149
149
slot.slotIndex = slotIndex;
150
150
RequestContext storage context = _requestContexts[requestId];
151
151
152
- require (slotState (slotId) == SlotState.Free, "Slot is not free " );
152
+ require (
153
+ slotState (slotId) == SlotState.Free ||
154
+ slotState (slotId) == SlotState.Repair,
155
+ "Slot is not free "
156
+ );
153
157
154
158
_startRequiringProofs (slotId, request.ask.proofProbability);
155
159
submitProof (slotId, proof);
156
160
157
161
slot.host = msg .sender ;
158
- slot.state = SlotState.Filled;
159
162
slot.filledAt = block .timestamp ;
160
163
161
164
context.slotsFilled += 1 ;
162
165
context.fundsToReturnToClient -= _slotPayout (requestId, slot.filledAt);
163
166
164
167
// Collect collateral
165
- uint256 collateralAmount = request.ask.collateral;
168
+ uint256 collateralAmount;
169
+ if (slotState (slotId) == SlotState.Repair) {
170
+ // Host is repairing a slot and is entitled for repair reward, so he gets "discounted collateral"
171
+ // in this way he gets "physically" the reward at the end of the request when the full amount of collateral
172
+ // is returned to him.
173
+ collateralAmount =
174
+ request.ask.collateral -
175
+ ((request.ask.collateral * _config.collateral.repairRewardPercentage) /
176
+ 100 );
177
+ } else {
178
+ collateralAmount = request.ask.collateral;
179
+ }
166
180
_transferFrom (msg .sender , collateralAmount);
167
181
_marketplaceTotals.received += collateralAmount;
168
- slot.currentCollateral = collateralAmount;
182
+ slot.currentCollateral = request.ask.collateral; // Even if he has collateral discounted, he is operating with full collateral
169
183
170
184
_addToMySlots (slot.host, slotId);
171
185
186
+ slot.state = SlotState.Filled;
172
187
emit SlotFilled (requestId, slotIndex);
173
- if (context.slotsFilled == request.ask.slots) {
188
+
189
+ if (
190
+ context.slotsFilled == request.ask.slots &&
191
+ context.state == RequestState.New // Only New requests can "start" the requests
192
+ ) {
174
193
context.state = RequestState.Started;
175
194
context.startedAt = block .timestamp ;
176
195
emit RequestFulfilled (requestId);
177
196
}
178
197
}
179
198
180
199
/**
181
- * @notice Frees a slot, paying out rewards and returning collateral for
200
+ * @notice Frees a slot, paying out rewards and returning collateral for
182
201
finished or cancelled requests to the host that has filled the slot.
183
202
* @param slotId id of the slot to free
184
203
* @dev The host that filled the slot must have initiated the transaction
@@ -190,7 +209,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
190
209
}
191
210
192
211
/**
193
- * @notice Frees a slot, paying out rewards and returning collateral for
212
+ * @notice Frees a slot, paying out rewards and returning collateral for
194
213
finished or cancelled requests.
195
214
* @param slotId id of the slot to free
196
215
* @param rewardRecipient address to send rewards to
@@ -280,7 +299,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
280
299
}
281
300
282
301
/**
283
- * @notice Abandons the slot without returning collateral, effectively slashing the
302
+ * @notice Abandons the slot without returning collateral, effectively slashing the
284
303
entire collateral.
285
304
* @param slotId SlotId of the slot to free.
286
305
* @dev _slots[slotId] is deleted, resetting _slots[slotId].currentCollateral
@@ -296,10 +315,13 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
296
315
context.fundsToReturnToClient += _slotPayout (requestId, slot.filledAt);
297
316
298
317
_removeFromMySlots (slot.host, slotId);
299
- uint256 slotIndex = slot.slotIndex;
300
- delete _slots[slotId];
318
+ delete _reservations[slotId]; // We purge all the reservations for the slot
319
+ slot.state = SlotState.Repair;
320
+ slot.filledAt = 0 ;
321
+ slot.currentCollateral = 0 ;
322
+ slot.host = address (0 );
301
323
context.slotsFilled -= 1 ;
302
- emit SlotFreed (requestId, slotIndex);
324
+ emit SlotFreed (requestId, slot. slotIndex);
303
325
_resetMissingProofs (slotId);
304
326
305
327
Request storage request = _requests[requestId];
@@ -337,7 +359,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
337
359
}
338
360
339
361
/**
340
- * @notice Pays out a host for duration of time that the slot was filled, and
362
+ * @notice Pays out a host for duration of time that the slot was filled, and
341
363
returns the collateral.
342
364
* @dev The payouts are sent to the rewardRecipient, and collateral is returned
343
365
to the host address.
@@ -367,7 +389,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
367
389
}
368
390
369
391
/**
370
- * @notice Withdraws remaining storage request funds back to the client that
392
+ * @notice Withdraws remaining storage request funds back to the client that
371
393
deposited them.
372
394
* @dev Request must be cancelled, failed or finished, and the
373
395
transaction must originate from the depositor address.
@@ -378,7 +400,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
378
400
}
379
401
380
402
/**
381
- * @notice Withdraws storage request funds to the provided address.
403
+ * @notice Withdraws storage request funds to the provided address.
382
404
* @dev Request must be expired, must be in RequestState.New, and the
383
405
transaction must originate from the depositer address.
384
406
* @param requestId the id of the request
0 commit comments