mirror of
https://github.com/status-im/codex-contracts-eth.git
synced 2025-02-07 14:13:28 +00:00
[marketplace] add isFinished
Add function `isFinished` that checks whethere the state has been set to `RequestState.Finished` (which is not being set yet) or if the contract was started (`RequestState.Started`) and the contract duration has lapsed. To facilitate `isFinished`, the contract start time (`startedAt`) was added to calculate the contract end time.
This commit is contained in:
parent
2170d6bd19
commit
1fff2f7295
@ -104,6 +104,7 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
emit SlotFilled(requestId, slotIndex, slotId);
|
emit SlotFilled(requestId, slotIndex, slotId);
|
||||||
if (context.slotsFilled == request.ask.slots) {
|
if (context.slotsFilled == request.ask.slots) {
|
||||||
context.state = RequestState.Started;
|
context.state = RequestState.Started;
|
||||||
|
context.startedAt = block.timestamp;
|
||||||
_extendLockExpiry(requestId, block.timestamp + request.ask.duration);
|
_extendLockExpiry(requestId, block.timestamp + request.ask.duration);
|
||||||
emit RequestFulfilled(requestId);
|
emit RequestFulfilled(requestId);
|
||||||
}
|
}
|
||||||
@ -146,10 +147,9 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
public
|
public
|
||||||
marketplaceInvariant
|
marketplaceInvariant
|
||||||
{
|
{
|
||||||
|
require(_isFinished(requestId), "Contract not ended");
|
||||||
bytes32 slotId = keccak256(abi.encode(requestId, slotIndex));
|
bytes32 slotId = keccak256(abi.encode(requestId, slotIndex));
|
||||||
require(block.timestamp > proofEnd(slotId), "Contract not ended");
|
Slot storage slot = _slot(slotId);
|
||||||
Slot storage slot = slots[slotId];
|
|
||||||
require(slot.host != address(0), "Slot empty");
|
|
||||||
require(!slot.hostPaid, "Already paid");
|
require(!slot.hostPaid, "Already paid");
|
||||||
uint256 amount = pricePerSlot(requests[requestId]);
|
uint256 amount = pricePerSlot(requests[requestId]);
|
||||||
funds.sent += amount;
|
funds.sent += amount;
|
||||||
@ -196,6 +196,21 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @notice Return true if the request state is RequestState.Finished or if the request duration has elapsed and the request was started.
|
||||||
|
/// @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) {
|
||||||
|
RequestContext memory context = requestContexts[requestId];
|
||||||
|
Request memory request = _request(requestId);
|
||||||
|
return
|
||||||
|
context.state == RequestState.Finished ||
|
||||||
|
(
|
||||||
|
context.state == RequestState.Started &&
|
||||||
|
block.timestamp > context.startedAt + request.ask.duration
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// @notice Return id of request that slot belongs to
|
/// @notice Return id of request that slot belongs to
|
||||||
/// @dev Returns requestId that is mapped to the slotId
|
/// @dev Returns requestId that is mapped to the slotId
|
||||||
/// @param slotId id of the slot
|
/// @param slotId id of the slot
|
||||||
@ -342,6 +357,7 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
struct RequestContext {
|
struct RequestContext {
|
||||||
uint256 slotsFilled;
|
uint256 slotsFilled;
|
||||||
RequestState state;
|
RequestState state;
|
||||||
|
uint256 startedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Slot {
|
struct Slot {
|
||||||
|
@ -324,7 +324,12 @@ describe("Marketplace", function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it("pays the host", async function () {
|
it("pays the host", async function () {
|
||||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
await waitUntilEnd()
|
await waitUntilEnd()
|
||||||
const startBalance = await token.balanceOf(host.address)
|
const startBalance = await token.balanceOf(host.address)
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
@ -332,10 +337,10 @@ describe("Marketplace", function () {
|
|||||||
expect(endBalance - startBalance).to.equal(pricePerSlot(request))
|
expect(endBalance - startBalance).to.equal(pricePerSlot(request))
|
||||||
})
|
})
|
||||||
|
|
||||||
it("is only allowed when the slot is filled", async function () {
|
it("is only allowed when the contract is finished", async function () {
|
||||||
await expect(
|
await expect(
|
||||||
marketplace.payoutSlot(slot.request, slot.index)
|
marketplace.payoutSlot(slot.request, slot.index)
|
||||||
).to.be.revertedWith("Slot empty")
|
).to.be.revertedWith("Contract not ended")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("is only allowed when the contract has ended", async function () {
|
it("is only allowed when the contract has ended", async function () {
|
||||||
@ -346,7 +351,12 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("can only be done once", async function () {
|
it("can only be done once", async function () {
|
||||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
await waitUntilEnd()
|
await waitUntilEnd()
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
await expect(
|
await expect(
|
||||||
@ -355,7 +365,12 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("cannot be filled again", async function () {
|
it("cannot be filled again", async function () {
|
||||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
await waitUntilEnd()
|
await waitUntilEnd()
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
await expect(marketplace.fillSlot(slot.request, slot.index, proof)).to.be
|
await expect(marketplace.fillSlot(slot.request, slot.index, proof)).to.be
|
||||||
|
@ -195,7 +195,6 @@ describe("Storage", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it("does not require proofs once cancelled", async function () {
|
it("does not require proofs once cancelled", async function () {
|
||||||
const id = slotId(slot)
|
const id = slotId(slot)
|
||||||
await storage.fillSlot(slot.request, slot.index, proof)
|
await storage.fillSlot(slot.request, slot.index, proof)
|
||||||
@ -287,7 +286,39 @@ describe("Storage", function () {
|
|||||||
await expect(storage.getSlot(id)).to.be.revertedWith("Slot empty")
|
await expect(storage.getSlot(id)).to.be.revertedWith("Slot empty")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe("contract state", function () {
|
||||||
|
it("isCancelled is true once request is cancelled", async function () {
|
||||||
|
await expect(await storage.isCancelled(slot.request)).to.equal(false)
|
||||||
|
await waitUntilExpired(request.expiry)
|
||||||
|
await expect(await storage.isCancelled(slot.request)).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("isSlotCancelled fails when slot is empty", async function () {
|
||||||
|
await expect(storage.isSlotCancelled(slotId(slot))).to.be.revertedWith(
|
||||||
|
"Slot empty"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("isSlotCancelled is true once request is cancelled", async function () {
|
||||||
|
await storage.fillSlot(slot.request, slot.index, proof)
|
||||||
|
await waitUntilExpired(request.expiry)
|
||||||
|
await expect(await storage.isSlotCancelled(slotId(slot))).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("isFinished is true once started and contract duration lapses", async function () {
|
||||||
|
await expect(await storage.isFinished(slot.request)).to.be.false
|
||||||
|
// fill all slots, should change state to RequestState.Started
|
||||||
|
await waitUntilAllSlotsFilled(
|
||||||
|
storage,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
|
await expect(await storage.isFinished(slot.request)).to.be.false
|
||||||
|
advanceTime(request.ask.duration + 1)
|
||||||
|
await expect(await storage.isFinished(slot.request)).to.be.true
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: implement checking of actual proofs of storage, instead of dummy bool
|
// TODO: implement checking of actual proofs of storage, instead of dummy bool
|
||||||
|
Loading…
x
Reference in New Issue
Block a user