[marketplace] Reward is paid out per second per slot
This commit is contained in:
parent
1d951ef8f8
commit
3e9fffb526
|
@ -39,9 +39,10 @@ contract Marketplace is Collateral, Proofs {
|
|||
|
||||
_createLock(id, request.expiry);
|
||||
|
||||
funds.received += request.ask.reward;
|
||||
funds.balance += request.ask.reward;
|
||||
transferFrom(msg.sender, request.ask.reward);
|
||||
uint256 amount = price(request);
|
||||
funds.received += amount;
|
||||
funds.balance += amount;
|
||||
transferFrom(msg.sender, amount);
|
||||
|
||||
emit StorageRequested(id, request.ask);
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ contract Marketplace is Collateral, Proofs {
|
|||
Slot storage slot = slots[slotId];
|
||||
require(slot.host != address(0), "Slot empty");
|
||||
require(!slot.hostPaid, "Already paid");
|
||||
uint256 amount = requests[requestId].ask.reward;
|
||||
uint256 amount = pricePerSlot(requests[requestId]);
|
||||
funds.sent += amount;
|
||||
funds.balance -= amount;
|
||||
slot.hostPaid = true;
|
||||
|
@ -111,6 +112,14 @@ contract Marketplace is Collateral, Proofs {
|
|||
return _end(contractId);
|
||||
}
|
||||
|
||||
function price(Request calldata request) private pure returns (uint256) {
|
||||
return request.ask.slots * request.ask.duration * request.ask.reward;
|
||||
}
|
||||
|
||||
function pricePerSlot(Request memory request) private pure returns (uint256) {
|
||||
return request.ask.duration * request.ask.reward;
|
||||
}
|
||||
|
||||
struct Request {
|
||||
address client;
|
||||
Ask ask;
|
||||
|
@ -123,7 +132,7 @@ contract Marketplace is Collateral, Proofs {
|
|||
uint256 size; // size of requested storage in number of bytes
|
||||
uint256 duration; // how long content should be stored (in seconds)
|
||||
uint256 proofProbability; // how often storage proofs are required
|
||||
uint256 reward; // reward that the client will pay (in number of tokens)
|
||||
uint256 reward; // amount of tokens paid per second per slot to hosts
|
||||
uint64 slots; // the total number of hosts that store the data set
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ const { expect } = require("chai")
|
|||
const { exampleRequest } = require("./examples")
|
||||
const { now, hours } = require("./time")
|
||||
const { requestId, slotId, askToArray } = require("./ids")
|
||||
const { price, pricePerSlot } = require("./price")
|
||||
const {
|
||||
snapshot,
|
||||
revert,
|
||||
|
@ -33,7 +34,7 @@ describe("Marketplace", function () {
|
|||
const TestToken = await ethers.getContractFactory("TestToken")
|
||||
token = await TestToken.deploy()
|
||||
for (account of [client, host1, host2, host3]) {
|
||||
await token.mint(account.address, 1000)
|
||||
await token.mint(account.address, 1_000_000_000)
|
||||
}
|
||||
|
||||
const Marketplace = await ethers.getContractFactory("Marketplace")
|
||||
|
@ -69,7 +70,7 @@ describe("Marketplace", function () {
|
|||
})
|
||||
|
||||
it("emits event when storage is requested", async function () {
|
||||
await token.approve(marketplace.address, request.ask.reward)
|
||||
await token.approve(marketplace.address, price(request))
|
||||
await expect(marketplace.requestStorage(request))
|
||||
.to.emit(marketplace, "StorageRequested")
|
||||
.withArgs(requestId(request), askToArray(request.ask))
|
||||
|
@ -77,14 +78,14 @@ describe("Marketplace", function () {
|
|||
|
||||
it("rejects request with invalid client address", async function () {
|
||||
let invalid = { ...request, client: host.address }
|
||||
await token.approve(marketplace.address, invalid.ask.reward)
|
||||
await token.approve(marketplace.address, price(invalid))
|
||||
await expect(marketplace.requestStorage(invalid)).to.be.revertedWith(
|
||||
"Invalid client address"
|
||||
)
|
||||
})
|
||||
|
||||
it("rejects request with insufficient payment", async function () {
|
||||
let insufficient = request.ask.reward - 1
|
||||
let insufficient = price(request) - 1
|
||||
await token.approve(marketplace.address, insufficient)
|
||||
await expect(marketplace.requestStorage(request)).to.be.revertedWith(
|
||||
"ERC20: insufficient allowance"
|
||||
|
@ -92,7 +93,7 @@ describe("Marketplace", function () {
|
|||
})
|
||||
|
||||
it("rejects resubmission of request", async function () {
|
||||
await token.approve(marketplace.address, request.ask.reward * 2)
|
||||
await token.approve(marketplace.address, price(request) * 2)
|
||||
await marketplace.requestStorage(request)
|
||||
await expect(marketplace.requestStorage(request)).to.be.revertedWith(
|
||||
"Request already exists"
|
||||
|
@ -103,7 +104,7 @@ describe("Marketplace", function () {
|
|||
describe("filling a slot", function () {
|
||||
beforeEach(async function () {
|
||||
switchAccount(client)
|
||||
await token.approve(marketplace.address, request.ask.reward)
|
||||
await token.approve(marketplace.address, price(request))
|
||||
await marketplace.requestStorage(request)
|
||||
switchAccount(host)
|
||||
await token.approve(marketplace.address, collateral)
|
||||
|
@ -160,7 +161,7 @@ describe("Marketplace", function () {
|
|||
it("is rejected when request is expired", async function () {
|
||||
switchAccount(client)
|
||||
let expired = { ...request, expiry: now() - hours(1) }
|
||||
await token.approve(marketplace.address, request.ask.reward)
|
||||
await token.approve(marketplace.address, price(request))
|
||||
await marketplace.requestStorage(expired)
|
||||
switchAccount(host)
|
||||
await expect(
|
||||
|
@ -179,7 +180,7 @@ describe("Marketplace", function () {
|
|||
describe("paying out a slot", function () {
|
||||
beforeEach(async function () {
|
||||
switchAccount(client)
|
||||
await token.approve(marketplace.address, request.ask.reward)
|
||||
await token.approve(marketplace.address, price(request))
|
||||
await marketplace.requestStorage(request)
|
||||
switchAccount(host)
|
||||
await token.approve(marketplace.address, collateral)
|
||||
|
@ -197,7 +198,7 @@ describe("Marketplace", function () {
|
|||
const startBalance = await token.balanceOf(host.address)
|
||||
await marketplace.payoutSlot(slot.request, slot.index)
|
||||
const endBalance = await token.balanceOf(host.address)
|
||||
expect(endBalance - startBalance).to.equal(request.ask.reward)
|
||||
expect(endBalance - startBalance).to.equal(pricePerSlot(request))
|
||||
})
|
||||
|
||||
it("is only allowed when the slot is filled", async function () {
|
||||
|
@ -234,7 +235,7 @@ describe("Marketplace", function () {
|
|||
describe("fulfilling a request", function () {
|
||||
beforeEach(async function () {
|
||||
switchAccount(client)
|
||||
await token.approve(marketplace.address, request.ask.reward)
|
||||
await token.approve(marketplace.address, price(request))
|
||||
await marketplace.requestStorage(request)
|
||||
switchAccount(host)
|
||||
await token.approve(marketplace.address, collateral)
|
||||
|
|
|
@ -6,6 +6,7 @@ const { exampleRequest } = require("./examples")
|
|||
const { advanceTime, advanceTimeTo, currentTime } = require("./evm")
|
||||
const { requestId, slotId } = require("./ids")
|
||||
const { periodic } = require("./time")
|
||||
const { price } = require("./price")
|
||||
|
||||
describe("Storage", function () {
|
||||
const proof = hexlify(randomBytes(42))
|
||||
|
@ -29,8 +30,8 @@ describe("Storage", function () {
|
|||
token = await ethers.getContract("TestToken")
|
||||
storage = await ethers.getContract("Storage")
|
||||
|
||||
await token.mint(client.address, 1000)
|
||||
await token.mint(host.address, 1000)
|
||||
await token.mint(client.address, 1_000_000_000)
|
||||
await token.mint(host.address, 1_000_000_000)
|
||||
|
||||
collateralAmount = await storage.collateralAmount()
|
||||
slashMisses = await storage.slashMisses()
|
||||
|
@ -44,7 +45,7 @@ describe("Storage", function () {
|
|||
}
|
||||
|
||||
switchAccount(client)
|
||||
await token.approve(storage.address, request.ask.reward)
|
||||
await token.approve(storage.address, price(request))
|
||||
await storage.requestStorage(request)
|
||||
switchAccount(host)
|
||||
await token.approve(storage.address, collateralAmount)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
function price(request) {
|
||||
return request.ask.slots * pricePerSlot(request)
|
||||
}
|
||||
|
||||
function pricePerSlot(request) {
|
||||
return request.ask.duration * request.ask.reward
|
||||
}
|
||||
|
||||
module.exports = { price, pricePerSlot }
|
Loading…
Reference in New Issue