mirror of
https://github.com/logos-storage/logos-storage-contracts-eth.git
synced 2026-01-05 23:03:12 +00:00
marketplace: remove accounting that is now done by vault
This commit is contained in:
parent
15c58e1a81
commit
9570404fba
@ -40,7 +40,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
error Marketplace_ProofNotSubmittedByHost();
|
error Marketplace_ProofNotSubmittedByHost();
|
||||||
error Marketplace_SlotIsFree();
|
error Marketplace_SlotIsFree();
|
||||||
error Marketplace_ReservationRequired();
|
error Marketplace_ReservationRequired();
|
||||||
error Marketplace_NothingToWithdraw();
|
|
||||||
error Marketplace_DurationExceedsLimit();
|
error Marketplace_DurationExceedsLimit();
|
||||||
|
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
@ -61,18 +60,8 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
mapping(RequestId => RequestContext) internal _requestContexts;
|
mapping(RequestId => RequestContext) internal _requestContexts;
|
||||||
mapping(SlotId => Slot) internal _slots;
|
mapping(SlotId => Slot) internal _slots;
|
||||||
|
|
||||||
MarketplaceTotals internal _marketplaceTotals;
|
|
||||||
|
|
||||||
struct RequestContext {
|
struct RequestContext {
|
||||||
RequestState state;
|
RequestState state;
|
||||||
/// @notice Tracks how much funds should be returned to the client as not all funds might be used for hosting the request
|
|
||||||
/// @dev The sum starts with the full reward amount for the request and is reduced every time a host fills a slot.
|
|
||||||
/// The reduction is calculated from the duration of time between the slot being filled and the request's end.
|
|
||||||
/// This is the amount that will be paid out to the host when the request successfully finishes.
|
|
||||||
/// @dev fundsToReturnToClient == 0 is used to signal that after request is terminated all the remaining funds were withdrawn.
|
|
||||||
/// This is possible, because technically it is not possible for this variable to reach 0 in "natural" way as
|
|
||||||
/// that would require all the slots to be filled at the same block as the request was created.
|
|
||||||
uint256 fundsToReturnToClient;
|
|
||||||
uint64 slotsFilled;
|
uint64 slotsFilled;
|
||||||
Timestamp startedAt;
|
Timestamp startedAt;
|
||||||
Timestamp endsAt;
|
Timestamp endsAt;
|
||||||
@ -182,10 +171,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
|
|
||||||
_addToMyRequests(request.client, id);
|
_addToMyRequests(request.client, id);
|
||||||
|
|
||||||
uint128 amount = request.maxPrice();
|
|
||||||
_requestContexts[id].fundsToReturnToClient = amount;
|
|
||||||
_marketplaceTotals.received += amount;
|
|
||||||
|
|
||||||
FundId fund = id.asFundId();
|
FundId fund = id.asFundId();
|
||||||
AccountId account = _vault.clientAccount(request.client);
|
AccountId account = _vault.clientAccount(request.client);
|
||||||
_vault.lock(
|
_vault.lock(
|
||||||
@ -193,7 +178,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
_requestContexts[id].expiresAt,
|
_requestContexts[id].expiresAt,
|
||||||
_requestContexts[id].endsAt
|
_requestContexts[id].endsAt
|
||||||
);
|
);
|
||||||
_transferToVault(request.client, fund, account, amount);
|
_transferToVault(request.client, fund, account, request.maxPrice());
|
||||||
|
|
||||||
emit StorageRequested(id, request.ask, _requestContexts[id].expiresAt);
|
emit StorageRequested(id, request.ask, _requestContexts[id].expiresAt);
|
||||||
}
|
}
|
||||||
@ -240,7 +225,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
submitProof(slotId, proof);
|
submitProof(slotId, proof);
|
||||||
|
|
||||||
context.slotsFilled += 1;
|
context.slotsFilled += 1;
|
||||||
context.fundsToReturnToClient -= _slotPayout(requestId, slot.filledAt);
|
|
||||||
|
|
||||||
// Collect collateral
|
// Collect collateral
|
||||||
uint128 collateralAmount;
|
uint128 collateralAmount;
|
||||||
@ -264,7 +248,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
_transferToVault(slot.host, fund, hostAccount, collateralAmount);
|
_transferToVault(slot.host, fund, hostAccount, collateralAmount);
|
||||||
_vault.flow(fund, clientAccount, hostAccount, rate);
|
_vault.flow(fund, clientAccount, hostAccount, rate);
|
||||||
|
|
||||||
_marketplaceTotals.received += collateralAmount;
|
|
||||||
slot.currentCollateral = collateralPerSlot; // Even if he has collateral discounted, he is operating with full collateral
|
slot.currentCollateral = collateralPerSlot; // Even if he has collateral discounted, he is operating with full collateral
|
||||||
|
|
||||||
_addToMySlots(slot.host, slotId);
|
_addToMySlots(slot.host, slotId);
|
||||||
@ -379,7 +362,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
|
|
||||||
uint128 validatorRewardAmount = (slashedAmount *
|
uint128 validatorRewardAmount = (slashedAmount *
|
||||||
_config.collateral.validatorRewardPercentage) / 100;
|
_config.collateral.validatorRewardPercentage) / 100;
|
||||||
_marketplaceTotals.sent += validatorRewardAmount;
|
|
||||||
|
|
||||||
FundId fund = slot.requestId.asFundId();
|
FundId fund = slot.requestId.asFundId();
|
||||||
AccountId hostAccount = _vault.hostAccount(slot.host, slot.slotIndex);
|
AccountId hostAccount = _vault.hostAccount(slot.host, slot.slotIndex);
|
||||||
@ -411,10 +393,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
RequestId requestId = slot.requestId;
|
RequestId requestId = slot.requestId;
|
||||||
RequestContext storage context = _requestContexts[requestId];
|
RequestContext storage context = _requestContexts[requestId];
|
||||||
|
|
||||||
// We need to refund the amount of payout of the current node to the `fundsToReturnToClient` so
|
|
||||||
// we keep correctly the track of the funds that needs to be returned at the end.
|
|
||||||
context.fundsToReturnToClient += _slotPayout(requestId, slot.filledAt);
|
|
||||||
|
|
||||||
Request storage request = _requests[requestId];
|
Request storage request = _requests[requestId];
|
||||||
|
|
||||||
FundId fund = requestId.asFundId();
|
FundId fund = requestId.asFundId();
|
||||||
@ -459,9 +437,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
_removeFromMyRequests(request.client, requestId);
|
_removeFromMyRequests(request.client, requestId);
|
||||||
_removeFromMySlots(slot.host, slotId);
|
_removeFromMySlots(slot.host, slotId);
|
||||||
|
|
||||||
uint256 payoutAmount = _slotPayout(requestId, slot.filledAt);
|
|
||||||
uint256 collateralAmount = slot.currentCollateral;
|
|
||||||
_marketplaceTotals.sent += (payoutAmount + collateralAmount);
|
|
||||||
slot.state = SlotState.Paid;
|
slot.state = SlotState.Paid;
|
||||||
FundId fund = requestId.asFundId();
|
FundId fund = requestId.asFundId();
|
||||||
AccountId account = _vault.hostAccount(slot.host, slot.slotIndex);
|
AccountId account = _vault.hostAccount(slot.host, slot.slotIndex);
|
||||||
@ -481,14 +456,6 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
) private requestIsKnown(requestId) {
|
) private requestIsKnown(requestId) {
|
||||||
Slot storage slot = _slots[slotId];
|
Slot storage slot = _slots[slotId];
|
||||||
_removeFromMySlots(slot.host, slotId);
|
_removeFromMySlots(slot.host, slotId);
|
||||||
|
|
||||||
uint256 payoutAmount = _slotPayout(
|
|
||||||
requestId,
|
|
||||||
slot.filledAt,
|
|
||||||
requestExpiry(requestId)
|
|
||||||
);
|
|
||||||
uint256 collateralAmount = slot.currentCollateral;
|
|
||||||
_marketplaceTotals.sent += (payoutAmount + collateralAmount);
|
|
||||||
slot.state = SlotState.Paid;
|
slot.state = SlotState.Paid;
|
||||||
FundId fund = requestId.asFundId();
|
FundId fund = requestId.asFundId();
|
||||||
AccountId account = _vault.hostAccount(slot.host, slot.slotIndex);
|
AccountId account = _vault.hostAccount(slot.host, slot.slotIndex);
|
||||||
@ -517,40 +484,16 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
revert Marketplace_InvalidState();
|
revert Marketplace_InvalidState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fundsToReturnToClient == 0 is used for "double-spend" protection, once the funds are withdrawn
|
context.state = state;
|
||||||
// then this variable is set to 0.
|
|
||||||
if (context.fundsToReturnToClient == 0)
|
|
||||||
revert Marketplace_NothingToWithdraw();
|
|
||||||
|
|
||||||
if (state == RequestState.Cancelled) {
|
if (state == RequestState.Cancelled) {
|
||||||
context.state = RequestState.Cancelled;
|
|
||||||
emit RequestCancelled(requestId);
|
emit RequestCancelled(requestId);
|
||||||
|
|
||||||
// `fundsToReturnToClient` currently tracks funds to be returned for requests that successfully finish.
|
|
||||||
// When requests are cancelled, funds earmarked for payment for the duration
|
|
||||||
// between request expiry and request end (for every slot that was filled), should be returned to the client.
|
|
||||||
// Update `fundsToReturnToClient` to reflect this.
|
|
||||||
context.fundsToReturnToClient +=
|
|
||||||
context.slotsFilled *
|
|
||||||
_slotPayout(requestId, requestExpiry(requestId));
|
|
||||||
} else if (state == RequestState.Failed) {
|
|
||||||
// For Failed requests the client is refunded whole amount.
|
|
||||||
context.fundsToReturnToClient = request.maxPrice();
|
|
||||||
} else {
|
|
||||||
context.state = RequestState.Finished;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_removeFromMyRequests(request.client, requestId);
|
_removeFromMyRequests(request.client, requestId);
|
||||||
|
|
||||||
uint256 amount = context.fundsToReturnToClient;
|
|
||||||
_marketplaceTotals.sent += amount;
|
|
||||||
|
|
||||||
FundId fund = requestId.asFundId();
|
FundId fund = requestId.asFundId();
|
||||||
AccountId account = _vault.clientAccount(request.client);
|
AccountId account = _vault.clientAccount(request.client);
|
||||||
_vault.withdraw(fund, account);
|
_vault.withdraw(fund, account);
|
||||||
|
|
||||||
// We zero out the funds tracking in order to prevent double-spends
|
|
||||||
context.fundsToReturnToClient = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function withdrawByValidator(RequestId requestId) public {
|
function withdrawByValidator(RequestId requestId) public {
|
||||||
@ -707,9 +650,4 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
|||||||
event SlotFilled(RequestId indexed requestId, uint64 slotIndex);
|
event SlotFilled(RequestId indexed requestId, uint64 slotIndex);
|
||||||
event SlotFreed(RequestId indexed requestId, uint64 slotIndex);
|
event SlotFreed(RequestId indexed requestId, uint64 slotIndex);
|
||||||
event RequestCancelled(RequestId indexed requestId);
|
event RequestCancelled(RequestId indexed requestId);
|
||||||
|
|
||||||
struct MarketplaceTotals {
|
|
||||||
uint256 received;
|
|
||||||
uint256 sent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -783,15 +783,17 @@ describe("Marketplace", function () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("rejects withdraw when already withdrawn", async function () {
|
it("does not withdraw more than once", async function () {
|
||||||
await waitUntilStarted(marketplace, request, proof, token)
|
await waitUntilStarted(marketplace, request, proof, token)
|
||||||
await waitUntilFinished(marketplace, requestId(request))
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
|
|
||||||
switchAccount(client)
|
switchAccount(client)
|
||||||
await marketplace.withdrawFunds(slot.request)
|
await marketplace.withdrawFunds(slot.request)
|
||||||
await expect(marketplace.withdrawFunds(slot.request)).to.be.revertedWith(
|
|
||||||
"Marketplace_NothingToWithdraw"
|
const startBalance = await token.balanceOf(client.address)
|
||||||
)
|
await marketplace.withdrawFunds(slot.request)
|
||||||
|
const endBalance = await token.balanceOf(client.address)
|
||||||
|
|
||||||
|
expect(endBalance - startBalance).to.equal(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("emits event once request is cancelled", async function () {
|
it("emits event once request is cancelled", async function () {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user