Disallow finishing of contract that wasn't started

This commit is contained in:
Mark Spanbroek 2022-03-22 12:32:14 +01:00 committed by markspanbroek
parent c606b455d6
commit 81c7dcd25a
2 changed files with 28 additions and 7 deletions

View File

@ -10,7 +10,7 @@ contract Storage is Collateral, Marketplace, Proofs {
uint256 public slashMisses; uint256 public slashMisses;
uint256 public slashPercentage; uint256 public slashPercentage;
mapping(bytes32 => bool) private finished; mapping(bytes32 => ContractState) private contractState;
constructor( constructor(
IERC20 token, IERC20 token,
@ -33,14 +33,15 @@ contract Storage is Collateral, Marketplace, Proofs {
Offer storage offer = _offer(id); Offer storage offer = _offer(id);
require(msg.sender == offer.host, "Only host can call this function"); require(msg.sender == offer.host, "Only host can call this function");
require(_selectedOffer(offer.requestId) == id, "Offer was not selected"); require(_selectedOffer(offer.requestId) == id, "Offer was not selected");
contractState[id] = ContractState.started;
Request storage request = _request(offer.requestId); Request storage request = _request(offer.requestId);
_expectProofs(id, request.proofProbability, request.duration); _expectProofs(id, request.proofProbability, request.duration);
} }
function finishContract(bytes32 id) public { function finishContract(bytes32 id) public {
require(contractState[id] == ContractState.started, "Contract not started");
require(block.timestamp > proofEnd(id), "Contract has not ended yet"); require(block.timestamp > proofEnd(id), "Contract has not ended yet");
require(!finished[id], "Contract already finished"); contractState[id] = ContractState.finished;
finished[id] = true;
Offer storage offer = _offer(id); Offer storage offer = _offer(id);
require(token.transfer(offer.host, offer.price), "Payment failed"); require(token.transfer(offer.host, offer.price), "Payment failed");
} }
@ -84,4 +85,10 @@ contract Storage is Collateral, Marketplace, Proofs {
_slash(offer.host, slashPercentage); _slash(offer.host, slashPercentage);
} }
} }
enum ContractState {
none,
started,
finished
}
} }

View File

@ -84,7 +84,6 @@ describe("Storage", function () {
describe("finishing the contract", function () { describe("finishing the contract", function () {
beforeEach(async function () { beforeEach(async function () {
switchAccount(host) switchAccount(host)
await storage.startContract(id)
}) })
async function waitUntilEnd() { async function waitUntilEnd() {
@ -93,12 +92,14 @@ describe("Storage", function () {
} }
it("unlocks the host collateral", async function () { it("unlocks the host collateral", async function () {
await storage.startContract(id)
await waitUntilEnd() await waitUntilEnd()
await storage.finishContract(id) await storage.finishContract(id)
await expect(storage.withdraw()).not.to.be.reverted await expect(storage.withdraw()).not.to.be.reverted
}) })
it("pays the host", async function () { it("pays the host", async function () {
await storage.startContract(id)
await waitUntilEnd() await waitUntilEnd()
const startBalance = await token.balanceOf(host.address) const startBalance = await token.balanceOf(host.address)
await storage.finishContract(id) await storage.finishContract(id)
@ -106,18 +107,31 @@ describe("Storage", function () {
expect(endBalance - startBalance).to.equal(offer.price) expect(endBalance - startBalance).to.equal(offer.price)
}) })
it("is only allowed when the contract has started", async function () {
await expect(storage.finishContract(id)).to.be.revertedWith(
"Contract not started"
)
})
it("is only allowed when end time has passed", async function () { it("is only allowed when end time has passed", async function () {
await storage.startContract(id)
await expect(storage.finishContract(id)).to.be.revertedWith( await expect(storage.finishContract(id)).to.be.revertedWith(
"Contract has not ended yet" "Contract has not ended yet"
) )
}) })
it("can only be done once", async function () { it("can only be done once", async function () {
await storage.startContract(id)
await waitUntilEnd() await waitUntilEnd()
await storage.finishContract(id) await storage.finishContract(id)
await expect(storage.finishContract(id)).to.be.revertedWith( await expect(storage.finishContract(id)).to.be.reverted
"Contract already finished" })
)
it("can not be restarted", async function () {
await storage.startContract(id)
await waitUntilEnd()
await storage.finishContract(id)
await expect(storage.startContract(id)).to.be.reverted
}) })
}) })