diff --git a/contracts/Storage.sol b/contracts/Storage.sol index 6e1ab5d..13ceb4c 100644 --- a/contracts/Storage.sol +++ b/contracts/Storage.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.0; import "./Contracts.sol"; import "./Proofs.sol"; +import "./Stakes.sol"; -contract Storage is Contracts, Proofs { +contract Storage is Contracts, Proofs, Stakes { + + constructor(IERC20 token) Stakes(token) {} function newContract( uint _duration, @@ -21,6 +24,7 @@ contract Storage is Contracts, Proofs { ) public { + require(_stake(_host) > 0, "Insufficient stake"); bytes32 id = _newContract( _duration, _size, @@ -102,4 +106,8 @@ contract Storage is Contracts, Proofs { function markProofAsMissing(bytes32 contractId, uint blocknumber) public { _markProofAsMissing(contractId, blocknumber); } + + function increaseStake(uint amount) public { + _increaseStake(amount); + } } diff --git a/test/Storage.test.js b/test/Storage.test.js index cbc5e0c..45c22ec 100644 --- a/test/Storage.test.js +++ b/test/Storage.test.js @@ -5,23 +5,31 @@ const { exampleRequest, exampleBid } = require("./examples") describe("Storage", function () { + const request = exampleRequest() + const bid = exampleBid() + + let storage + let token + let client, host + + beforeEach(async function () { + [client, host] = await ethers.getSigners() + let Token = await ethers.getContractFactory("TestToken") + let StorageContracts = await ethers.getContractFactory("Storage") + token = await Token.connect(host).deploy() + storage = await StorageContracts.deploy(token.address) + }) + describe("creating a new storage contract", function () { - const request = exampleRequest() - const bid = exampleBid() - - let contracts - let client, host let id beforeEach(async function () { - [client, host] = await ethers.getSigners() - let StorageContracts = await ethers.getContractFactory("Storage") - contracts = await StorageContracts.deploy() + await token.approve(storage.address, 20) + await storage.connect(host).increaseStake(20) let requestHash = hashRequest(request) let bidHash = hashBid({...bid, requestHash}) - id = bidHash - await contracts.newContract( + await storage.newContract( request.duration, request.size, request.contentHash, @@ -34,26 +42,49 @@ describe("Storage", function () { await sign(client, requestHash), await sign(host, bidHash) ) + id = bidHash }) it("created the contract", async function () { - expect(await contracts.duration(id)).to.equal(request.duration) - expect(await contracts.size(id)).to.equal(request.size) - expect(await contracts.contentHash(id)).to.equal(request.contentHash) - expect(await contracts.price(id)).to.equal(bid.price) - expect(await contracts.host(id)).to.equal(await host.getAddress()) + expect(await storage.duration(id)).to.equal(request.duration) + expect(await storage.size(id)).to.equal(request.size) + expect(await storage.contentHash(id)).to.equal(request.contentHash) + expect(await storage.price(id)).to.equal(bid.price) + expect(await storage.host(id)).to.equal(await host.getAddress()) }) it("requires storage proofs", async function (){ - expect(await contracts.proofPeriod(id)).to.equal(request.proofPeriod) - expect(await contracts.proofTimeout(id)).to.equal(request.proofTimeout) + expect(await storage.proofPeriod(id)).to.equal(request.proofPeriod) + expect(await storage.proofTimeout(id)).to.equal(request.proofTimeout) }) }) + + it("doesn't create contract when insufficient stake", async function () { + let requestHash = hashRequest(request) + let bidHash = hashBid({...bid, requestHash}) + await expect(storage.newContract( + request.duration, + request.size, + request.contentHash, + request.proofPeriod, + request.proofTimeout, + request.nonce, + bid.price, + await host.getAddress(), + bid.bidExpiry, + await sign(client, requestHash), + await sign(host, bidHash) + )).to.be.revertedWith("Insufficient stake") + }) }) -// TODO: implement checking of actual proofs of storage, instead of dummy bool -// TODO: payment on constructor +// TODO: configurable amount of stake +// TODO: lock up stake when new contract +// TODO: unlock stake at end of contract +// TODO: payment when new contract // TODO: contract start and timeout +// TODO: failure to start contract burns host and client +// TODO: implement checking of actual proofs of storage, instead of dummy bool // TODO: only allow proofs after start of contract +// TODO: proofs no longer required after contract duration // TODO: payout -// TODO: stake