[marketplace] formatting
This commit is contained in:
parent
42d4778dcc
commit
03e5546121
|
@ -33,7 +33,6 @@ contract Marketplace is Proofs, StateRetrieval {
|
||||||
SlotState state;
|
SlotState state;
|
||||||
RequestId requestId;
|
RequestId requestId;
|
||||||
uint256 slotIndex;
|
uint256 slotIndex;
|
||||||
|
|
||||||
/// @notice Tracks the current amount of host's collateral that is to be payed out at the end of Slot's lifespan.
|
/// @notice Tracks the current amount of host's collateral that is to be payed out at the end of Slot's lifespan.
|
||||||
/// @dev When Slot is filled, the collateral is collected in amount of request.ask.collateral
|
/// @dev When Slot is filled, the collateral is collected in amount of request.ask.collateral
|
||||||
/// @dev When Host is slashed for missing a proof the slashed amount is reflected in this variable
|
/// @dev When Host is slashed for missing a proof the slashed amount is reflected in this variable
|
||||||
|
@ -52,9 +51,20 @@ contract Marketplace is Proofs, StateRetrieval {
|
||||||
) Proofs(configuration.proofs) {
|
) Proofs(configuration.proofs) {
|
||||||
token = token_;
|
token = token_;
|
||||||
|
|
||||||
require(configuration.collateral.repairRewardPercentage <= 100, "Must be less than 100");
|
require(
|
||||||
require(configuration.collateral.slashPercentage <= 100, "Must be less than 100");
|
configuration.collateral.repairRewardPercentage <= 100,
|
||||||
require(configuration.collateral.maxNumberOfSlashes * configuration.collateral.slashPercentage <= 100, "Total slash percentage must be less then 100");
|
"Must be less than 100"
|
||||||
|
);
|
||||||
|
require(
|
||||||
|
configuration.collateral.slashPercentage <= 100,
|
||||||
|
"Must be less than 100"
|
||||||
|
);
|
||||||
|
require(
|
||||||
|
configuration.collateral.maxNumberOfSlashes *
|
||||||
|
configuration.collateral.slashPercentage <=
|
||||||
|
100,
|
||||||
|
"Maximum slashing exceeds 100%"
|
||||||
|
);
|
||||||
config = configuration;
|
config = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,9 +147,13 @@ contract Marketplace is Proofs, StateRetrieval {
|
||||||
Request storage request = _requests[slot.requestId];
|
Request storage request = _requests[slot.requestId];
|
||||||
|
|
||||||
if (missingProofs(slotId) % config.collateral.slashCriterion == 0) {
|
if (missingProofs(slotId) % config.collateral.slashCriterion == 0) {
|
||||||
uint256 slashedAmount = (request.ask.collateral * config.collateral.slashPercentage) / 100;
|
uint256 slashedAmount = (request.ask.collateral *
|
||||||
|
config.collateral.slashPercentage) / 100;
|
||||||
slot.currentCollateral -= slashedAmount;
|
slot.currentCollateral -= slashedAmount;
|
||||||
if (missingProofs(slotId) / config.collateral.slashCriterion >= config.collateral.maxNumberOfSlashes) {
|
if (
|
||||||
|
missingProofs(slotId) / config.collateral.slashCriterion >=
|
||||||
|
config.collateral.maxNumberOfSlashes
|
||||||
|
) {
|
||||||
// When the number of slashings is at or above the allowed amount,
|
// When the number of slashings is at or above the allowed amount,
|
||||||
// free the slot.
|
// free the slot.
|
||||||
_forciblyFreeSlot(slotId);
|
_forciblyFreeSlot(slotId);
|
||||||
|
@ -157,7 +171,7 @@ contract Marketplace is Proofs, StateRetrieval {
|
||||||
delete _slots[slotId];
|
delete _slots[slotId];
|
||||||
context.slotsFilled -= 1;
|
context.slotsFilled -= 1;
|
||||||
emit SlotFreed(requestId, slotId);
|
emit SlotFreed(requestId, slotId);
|
||||||
resetMissingProofs(slotId);
|
_resetMissingProofs(slotId);
|
||||||
|
|
||||||
Request storage request = _requests[requestId];
|
Request storage request = _requests[requestId];
|
||||||
uint256 slotsLost = request.ask.slots - context.slotsFilled;
|
uint256 slotsLost = request.ask.slots - context.slotsFilled;
|
||||||
|
@ -185,7 +199,8 @@ contract Marketplace is Proofs, StateRetrieval {
|
||||||
|
|
||||||
_removeFromMySlots(slot.host, slotId);
|
_removeFromMySlots(slot.host, slotId);
|
||||||
|
|
||||||
uint256 amount = _requests[requestId].pricePerSlot() + slot.currentCollateral;
|
uint256 amount = _requests[requestId].pricePerSlot() +
|
||||||
|
slot.currentCollateral;
|
||||||
_marketplaceTotals.sent += amount;
|
_marketplaceTotals.sent += amount;
|
||||||
slot.state = SlotState.Paid;
|
slot.state = SlotState.Paid;
|
||||||
require(token.transfer(slot.host, amount), "Payment failed");
|
require(token.transfer(slot.host, amount), "Payment failed");
|
||||||
|
@ -216,12 +231,9 @@ contract Marketplace is Proofs, StateRetrieval {
|
||||||
require(token.transfer(msg.sender, amount), "Withdraw failed");
|
require(token.transfer(msg.sender, amount), "Withdraw failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActiveSlot(SlotId slotId)
|
function getActiveSlot(
|
||||||
public
|
SlotId slotId
|
||||||
view
|
) public view slotIsNotFree(slotId) returns (ActiveSlot memory) {
|
||||||
slotIsNotFree(slotId)
|
|
||||||
returns (ActiveSlot memory)
|
|
||||||
{
|
|
||||||
Slot storage slot = _slots[slotId];
|
Slot storage slot = _slots[slotId];
|
||||||
ActiveSlot memory activeSlot;
|
ActiveSlot memory activeSlot;
|
||||||
activeSlot.request = _requests[slot.requestId];
|
activeSlot.request = _requests[slot.requestId];
|
||||||
|
|
|
@ -25,7 +25,7 @@ abstract contract Proofs is Periods {
|
||||||
return _missed[slotId];
|
return _missed[slotId];
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetMissingProofs(SlotId slotId) internal {
|
function _resetMissingProofs(SlotId slotId) internal {
|
||||||
_missed[slotId] = 0;
|
_missed[slotId] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ const {
|
||||||
currentTime,
|
currentTime,
|
||||||
} = require("./evm")
|
} = require("./evm")
|
||||||
|
|
||||||
describe('Marketplace constructor', function () {
|
describe("Marketplace constructor", function () {
|
||||||
let Marketplace, token, config
|
let Marketplace, token, config
|
||||||
|
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
|
@ -51,21 +51,21 @@ describe('Marketplace constructor', function () {
|
||||||
it(`should reject for ${property} overflowing percentage values`, async () => {
|
it(`should reject for ${property} overflowing percentage values`, async () => {
|
||||||
config.collateral[property] = 101
|
config.collateral[property] = 101
|
||||||
|
|
||||||
await expect(Marketplace.deploy(token.address, config)).to.be.revertedWith(
|
await expect(
|
||||||
"Must be less than 100"
|
Marketplace.deploy(token.address, config)
|
||||||
)
|
).to.be.revertedWith("Must be less than 100")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
testPercentageOverflow('repairRewardPercentage')
|
testPercentageOverflow("repairRewardPercentage")
|
||||||
testPercentageOverflow('slashPercentage')
|
testPercentageOverflow("slashPercentage")
|
||||||
|
|
||||||
it('should reject when total slash percentage exceeds 100%', async () => {
|
it("should reject when total slash percentage exceeds 100%", async () => {
|
||||||
config.collateral.slashPercentage = 1
|
config.collateral.slashPercentage = 1
|
||||||
config.collateral.maxNumberOfSlashes = 101
|
config.collateral.maxNumberOfSlashes = 101
|
||||||
|
|
||||||
await expect(Marketplace.deploy(token.address, config)).to.be.revertedWith(
|
await expect(Marketplace.deploy(token.address, config)).to.be.revertedWith(
|
||||||
"Total slash percentage must be less then 100"
|
"Maximum slashing exceeds 100%"
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -250,7 +250,10 @@ describe("Marketplace", function () {
|
||||||
|
|
||||||
it("fails when all slots are already filled", async function () {
|
it("fails when all slots are already filled", async function () {
|
||||||
const lastSlot = request.ask.slots - 1
|
const lastSlot = request.ask.slots - 1
|
||||||
await token.approve(marketplace.address, request.ask.collateral * lastSlot)
|
await token.approve(
|
||||||
|
marketplace.address,
|
||||||
|
request.ask.collateral * lastSlot
|
||||||
|
)
|
||||||
await token.approve(marketplace.address, price(request) * lastSlot)
|
await token.approve(marketplace.address, price(request) * lastSlot)
|
||||||
for (let i = 0; i <= lastSlot; i++) {
|
for (let i = 0; i <= lastSlot; i++) {
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
await marketplace.fillSlot(slot.request, i, proof)
|
||||||
|
@ -278,11 +281,11 @@ describe("Marketplace", function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("collects only requested collateral and not more", async function () {
|
it("collects only requested collateral and not more", async function () {
|
||||||
await token.approve(marketplace.address, request.ask.collateral*2)
|
await token.approve(marketplace.address, request.ask.collateral * 2)
|
||||||
const startBalanace = await token.balanceOf(host.address)
|
const startBalanace = await token.balanceOf(host.address)
|
||||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||||
const endBalance = await token.balanceOf(host.address)
|
const endBalance = await token.balanceOf(host.address)
|
||||||
expect(startBalanace-endBalance).to.eq(request.ask.collateral)
|
expect(startBalanace - endBalance).to.eq(request.ask.collateral)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -394,7 +397,9 @@ describe("Marketplace", function () {
|
||||||
const startBalance = await token.balanceOf(host.address)
|
const startBalance = await token.balanceOf(host.address)
|
||||||
await marketplace.freeSlot(slotId(slot))
|
await marketplace.freeSlot(slotId(slot))
|
||||||
const endBalance = await token.balanceOf(host.address)
|
const endBalance = await token.balanceOf(host.address)
|
||||||
expect(endBalance - startBalance).to.equal(pricePerSlot(request) + request.ask.collateral)
|
expect(endBalance - startBalance).to.equal(
|
||||||
|
pricePerSlot(request) + request.ask.collateral
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("pays the host when contract was cancelled", async function () {
|
it("pays the host when contract was cancelled", async function () {
|
||||||
|
@ -443,7 +448,10 @@ describe("Marketplace", function () {
|
||||||
|
|
||||||
it("emits event when all slots are filled", async function () {
|
it("emits event when all slots are filled", async function () {
|
||||||
const lastSlot = request.ask.slots - 1
|
const lastSlot = request.ask.slots - 1
|
||||||
await token.approve(marketplace.address, request.ask.collateral * lastSlot)
|
await token.approve(
|
||||||
|
marketplace.address,
|
||||||
|
request.ask.collateral * lastSlot
|
||||||
|
)
|
||||||
for (let i = 0; i < lastSlot; i++) {
|
for (let i = 0; i < lastSlot; i++) {
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
await marketplace.fillSlot(slot.request, i, proof)
|
||||||
}
|
}
|
||||||
|
@ -465,7 +473,10 @@ describe("Marketplace", function () {
|
||||||
})
|
})
|
||||||
it("fails when all slots are already filled", async function () {
|
it("fails when all slots are already filled", async function () {
|
||||||
const lastSlot = request.ask.slots - 1
|
const lastSlot = request.ask.slots - 1
|
||||||
await token.approve(marketplace.address, request.ask.collateral * (lastSlot + 1))
|
await token.approve(
|
||||||
|
marketplace.address,
|
||||||
|
request.ask.collateral * (lastSlot + 1)
|
||||||
|
)
|
||||||
for (let i = 0; i <= lastSlot; i++) {
|
for (let i = 0; i <= lastSlot; i++) {
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
await marketplace.fillSlot(slot.request, i, proof)
|
||||||
}
|
}
|
||||||
|
@ -501,7 +512,10 @@ describe("Marketplace", function () {
|
||||||
it("rejects withdraw when in wrong state", async function () {
|
it("rejects withdraw when in wrong state", async function () {
|
||||||
// fill all slots, should change state to RequestState.Started
|
// fill all slots, should change state to RequestState.Started
|
||||||
const lastSlot = request.ask.slots - 1
|
const lastSlot = request.ask.slots - 1
|
||||||
await token.approve(marketplace.address, request.ask.collateral * (lastSlot + 1))
|
await token.approve(
|
||||||
|
marketplace.address,
|
||||||
|
request.ask.collateral * (lastSlot + 1)
|
||||||
|
)
|
||||||
for (let i = 0; i <= lastSlot; i++) {
|
for (let i = 0; i <= lastSlot; i++) {
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
await marketplace.fillSlot(slot.request, i, proof)
|
||||||
}
|
}
|
||||||
|
@ -569,7 +583,10 @@ describe("Marketplace", function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("does not change to 'Failed' before it is started", async function () {
|
it("does not change to 'Failed' before it is started", async function () {
|
||||||
await token.approve(marketplace.address, request.ask.collateral * (request.ask.maxSlotLoss + 1))
|
await token.approve(
|
||||||
|
marketplace.address,
|
||||||
|
request.ask.collateral * (request.ask.maxSlotLoss + 1)
|
||||||
|
)
|
||||||
for (let i = 0; i <= request.ask.maxSlotLoss; i++) {
|
for (let i = 0; i <= request.ask.maxSlotLoss; i++) {
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
await marketplace.fillSlot(slot.request, i, proof)
|
||||||
}
|
}
|
||||||
|
@ -701,7 +718,7 @@ describe("Marketplace", function () {
|
||||||
(await marketplace.isProofRequired(id)) &&
|
(await marketplace.isProofRequired(id)) &&
|
||||||
(await marketplace.getPointer(id)) < 250
|
(await marketplace.getPointer(id)) < 250
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await advanceTime(period)
|
await advanceTime(period)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -774,7 +791,7 @@ describe("Marketplace", function () {
|
||||||
(await marketplace.isProofRequired(id)) &&
|
(await marketplace.isProofRequired(id)) &&
|
||||||
(await marketplace.getPointer(id)) < 250
|
(await marketplace.getPointer(id)) < 250
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await advanceTime(period)
|
await advanceTime(period)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -799,42 +816,67 @@ describe("Marketplace", function () {
|
||||||
await advanceTime(period)
|
await advanceTime(period)
|
||||||
await marketplace.markProofAsMissing(id, missedPeriod)
|
await marketplace.markProofAsMissing(id, missedPeriod)
|
||||||
}
|
}
|
||||||
const expectedBalance = (request.ask.collateral * (100 - slashPercentage)) / 100
|
const expectedBalance =
|
||||||
|
(request.ask.collateral * (100 - slashPercentage)) / 100
|
||||||
|
|
||||||
expect(BigNumber.from(expectedBalance).eq(await marketplace.getSlotCollateral(id)))
|
expect(
|
||||||
|
BigNumber.from(expectedBalance).eq(
|
||||||
|
await marketplace.getSlotCollateral(id)
|
||||||
|
)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("frees slot when collateral slashed below minimum threshold", async function () {
|
it("frees slot when collateral slashed below minimum threshold", async function () {
|
||||||
const minimum = request.ask.collateral - (request.ask.collateral*config.collateral.maxNumberOfSlashes*config.collateral.slashPercentage)/100
|
const minimum =
|
||||||
|
request.ask.collateral -
|
||||||
|
(request.ask.collateral *
|
||||||
|
config.collateral.maxNumberOfSlashes *
|
||||||
|
config.collateral.slashPercentage) /
|
||||||
|
100
|
||||||
await waitUntilStarted(marketplace, request, proof, token)
|
await waitUntilStarted(marketplace, request, proof, token)
|
||||||
while ((await marketplace.slotState(slotId(slot))) === SlotState.Filled) {
|
while ((await marketplace.slotState(slotId(slot))) === SlotState.Filled) {
|
||||||
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.gt(minimum)
|
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.gt(
|
||||||
|
minimum
|
||||||
|
)
|
||||||
await waitUntilProofIsRequired(slotId(slot))
|
await waitUntilProofIsRequired(slotId(slot))
|
||||||
const missedPeriod = periodOf(await currentTime())
|
const missedPeriod = periodOf(await currentTime())
|
||||||
await advanceTime(period)
|
await advanceTime(period)
|
||||||
await marketplace.markProofAsMissing(slotId(slot), missedPeriod)
|
await marketplace.markProofAsMissing(slotId(slot), missedPeriod)
|
||||||
}
|
}
|
||||||
expect(await marketplace.slotState(slotId(slot))).to.equal(SlotState.Free)
|
expect(await marketplace.slotState(slotId(slot))).to.equal(SlotState.Free)
|
||||||
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.lte(minimum)
|
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.lte(
|
||||||
|
minimum
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("free slot when minimum reached and resets missed proof counter", async function () {
|
it("free slot when minimum reached and resets missed proof counter", async function () {
|
||||||
const minimum = request.ask.collateral - (request.ask.collateral*config.collateral.maxNumberOfSlashes*config.collateral.slashPercentage)/100
|
const minimum =
|
||||||
|
request.ask.collateral -
|
||||||
|
(request.ask.collateral *
|
||||||
|
config.collateral.maxNumberOfSlashes *
|
||||||
|
config.collateral.slashPercentage) /
|
||||||
|
100
|
||||||
await waitUntilStarted(marketplace, request, proof, token)
|
await waitUntilStarted(marketplace, request, proof, token)
|
||||||
let missedProofs = 0
|
let missedProofs = 0
|
||||||
while ((await marketplace.slotState(slotId(slot))) === SlotState.Filled) {
|
while ((await marketplace.slotState(slotId(slot))) === SlotState.Filled) {
|
||||||
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.gt(minimum)
|
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.gt(
|
||||||
|
minimum
|
||||||
|
)
|
||||||
await waitUntilProofIsRequired(slotId(slot))
|
await waitUntilProofIsRequired(slotId(slot))
|
||||||
const missedPeriod = periodOf(await currentTime())
|
const missedPeriod = periodOf(await currentTime())
|
||||||
await advanceTime(period)
|
await advanceTime(period)
|
||||||
expect(await marketplace.missingProofs(slotId(slot))).to.equal(missedProofs)
|
expect(await marketplace.missingProofs(slotId(slot))).to.equal(
|
||||||
|
missedProofs
|
||||||
|
)
|
||||||
await marketplace.markProofAsMissing(slotId(slot), missedPeriod)
|
await marketplace.markProofAsMissing(slotId(slot), missedPeriod)
|
||||||
missedProofs += 1
|
missedProofs += 1
|
||||||
}
|
}
|
||||||
expect(await marketplace.slotState(slotId(slot))).to.equal(SlotState.Free)
|
expect(await marketplace.slotState(slotId(slot))).to.equal(SlotState.Free)
|
||||||
expect(await marketplace.missingProofs(slotId(slot))).to.equal(0)
|
expect(await marketplace.missingProofs(slotId(slot))).to.equal(0)
|
||||||
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.lte(minimum)
|
expect(await marketplace.getSlotCollateral(slotId(slot))).to.be.lte(
|
||||||
|
minimum
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue