From 8bb8441bceb7acf6652fa820e21ece38e5d17130 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Thu, 4 Nov 2021 14:19:58 +0100 Subject: [PATCH] Slash host stake when too many proofs are missing --- contracts/Storage.sol | 20 +++++++++++++++++++- test/Storage.test.js | 31 ++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/contracts/Storage.sol b/contracts/Storage.sol index 25d8717..49beb0b 100644 --- a/contracts/Storage.sol +++ b/contracts/Storage.sol @@ -8,11 +8,22 @@ import "./Stakes.sol"; contract Storage is Contracts, Proofs, Stakes { uint private stakeAmount; + uint private slashMisses; + uint private slashPercentage; mapping(bytes32=>bool) private finished; - constructor(IERC20 token, uint _stakeAmount) Stakes(token) { + constructor( + IERC20 token, + uint _stakeAmount, + uint _slashMisses, + uint _slashPercentage + ) + Stakes(token) + { stakeAmount = _stakeAmount; + slashMisses = _slashMisses; + slashPercentage = _slashPercentage; } function newContract( @@ -101,6 +112,10 @@ contract Storage is Contracts, Proofs, Stakes { return _missed(contractId); } + function stake(address account) public view returns (uint) { + return _stake(account); + } + function isProofRequired( bytes32 contractId, uint blocknumber @@ -133,6 +148,9 @@ contract Storage is Contracts, Proofs, Stakes { function markProofAsMissing(bytes32 contractId, uint blocknumber) public { _markProofAsMissing(contractId, blocknumber); + if (_missed(contractId) % slashMisses == 0) { + _slash(host(contractId), slashPercentage); + } } function increaseStake(uint amount) public { diff --git a/test/Storage.test.js b/test/Storage.test.js index 29ab4bf..e4dd739 100644 --- a/test/Storage.test.js +++ b/test/Storage.test.js @@ -7,6 +7,8 @@ const { mineBlock, minedBlockNumber } = require ("./mining") describe("Storage", function () { const stakeAmount = 100 + const slashMisses = 3 + const slashPercentage = 10 const request = exampleRequest() const bid = exampleBid() @@ -19,7 +21,9 @@ describe("Storage", function () { let Token = await ethers.getContractFactory("TestToken") let StorageContracts = await ethers.getContractFactory("Storage") token = await Token.deploy([client.address, host.address]) - storage = await StorageContracts.deploy(token.address, stakeAmount) + storage = await StorageContracts.deploy( + token.address, stakeAmount, slashMisses, slashPercentage + ) }) describe("creating a new storage contract", function () { @@ -123,6 +127,29 @@ describe("Storage", function () { ).to.be.revertedWith("Contract already finished") }) }) + + describe("slashing when missing proofs", function () { + + async function ensureProofIsMissing() { + while (!await storage.isProofRequired(id, await minedBlockNumber())) { + mineBlock() + } + const blocknumber = await minedBlockNumber() + for (let i=0; i