Slash host stake when too many proofs are missing
This commit is contained in:
parent
50bab88447
commit
8bb8441bce
|
@ -8,11 +8,22 @@ import "./Stakes.sol";
|
||||||
contract Storage is Contracts, Proofs, Stakes {
|
contract Storage is Contracts, Proofs, Stakes {
|
||||||
|
|
||||||
uint private stakeAmount;
|
uint private stakeAmount;
|
||||||
|
uint private slashMisses;
|
||||||
|
uint private slashPercentage;
|
||||||
|
|
||||||
mapping(bytes32=>bool) private finished;
|
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;
|
stakeAmount = _stakeAmount;
|
||||||
|
slashMisses = _slashMisses;
|
||||||
|
slashPercentage = _slashPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
function newContract(
|
function newContract(
|
||||||
|
@ -101,6 +112,10 @@ contract Storage is Contracts, Proofs, Stakes {
|
||||||
return _missed(contractId);
|
return _missed(contractId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stake(address account) public view returns (uint) {
|
||||||
|
return _stake(account);
|
||||||
|
}
|
||||||
|
|
||||||
function isProofRequired(
|
function isProofRequired(
|
||||||
bytes32 contractId,
|
bytes32 contractId,
|
||||||
uint blocknumber
|
uint blocknumber
|
||||||
|
@ -133,6 +148,9 @@ contract Storage is Contracts, Proofs, Stakes {
|
||||||
|
|
||||||
function markProofAsMissing(bytes32 contractId, uint blocknumber) public {
|
function markProofAsMissing(bytes32 contractId, uint blocknumber) public {
|
||||||
_markProofAsMissing(contractId, blocknumber);
|
_markProofAsMissing(contractId, blocknumber);
|
||||||
|
if (_missed(contractId) % slashMisses == 0) {
|
||||||
|
_slash(host(contractId), slashPercentage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function increaseStake(uint amount) public {
|
function increaseStake(uint amount) public {
|
||||||
|
|
|
@ -7,6 +7,8 @@ const { mineBlock, minedBlockNumber } = require ("./mining")
|
||||||
describe("Storage", function () {
|
describe("Storage", function () {
|
||||||
|
|
||||||
const stakeAmount = 100
|
const stakeAmount = 100
|
||||||
|
const slashMisses = 3
|
||||||
|
const slashPercentage = 10
|
||||||
const request = exampleRequest()
|
const request = exampleRequest()
|
||||||
const bid = exampleBid()
|
const bid = exampleBid()
|
||||||
|
|
||||||
|
@ -19,7 +21,9 @@ describe("Storage", function () {
|
||||||
let Token = await ethers.getContractFactory("TestToken")
|
let Token = await ethers.getContractFactory("TestToken")
|
||||||
let StorageContracts = await ethers.getContractFactory("Storage")
|
let StorageContracts = await ethers.getContractFactory("Storage")
|
||||||
token = await Token.deploy([client.address, host.address])
|
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 () {
|
describe("creating a new storage contract", function () {
|
||||||
|
@ -123,6 +127,29 @@ describe("Storage", function () {
|
||||||
).to.be.revertedWith("Contract already finished")
|
).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<request.proofTimeout; i++) {
|
||||||
|
mineBlock()
|
||||||
|
}
|
||||||
|
await storage.markProofAsMissing(id, blocknumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
it("reduces stake when too many proofs are missing", async function () {
|
||||||
|
await storage.connect(host).startContract(id)
|
||||||
|
for (let i=0; i<slashMisses; i++) {
|
||||||
|
await ensureProofIsMissing()
|
||||||
|
}
|
||||||
|
const expectedStake = stakeAmount * (100 - slashPercentage) / 100
|
||||||
|
expect(await storage.stake(host.address)).to.equal(expectedStake)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("doesn't create contract with insufficient stake", async function () {
|
it("doesn't create contract with insufficient stake", async function () {
|
||||||
|
@ -168,9 +195,7 @@ describe("Storage", function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: contract start and timeout
|
|
||||||
// TODO: failure to start contract burns host and client
|
// TODO: failure to start contract burns host and client
|
||||||
// TODO: implement checking of actual proofs of storage, instead of dummy bool
|
// TODO: implement checking of actual proofs of storage, instead of dummy bool
|
||||||
// TODO: slash stake when too many missed proofs
|
|
||||||
// TODO: allow other host to take over contract when too many missed proofs
|
// TODO: allow other host to take over contract when too many missed proofs
|
||||||
// TODO: small partial payouts when proofs are being submitted
|
// TODO: small partial payouts when proofs are being submitted
|
||||||
|
|
Loading…
Reference in New Issue