diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index bb2cd1b..58c8854 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -42,6 +42,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableSet for EnumerableSet.AddressSet; using Requests for Request; + using AskHelpers for Ask; IERC20 private immutable _token; MarketplaceConfig private _config; @@ -72,14 +73,20 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { SlotState state; RequestId requestId; /// @notice Timestamp that signals when slot was filled - /// @dev Used for calculating payouts as hosts are paid based on time they actually host the content + /// @dev Used for calculating payouts as hosts are paid + /// based on time they actually host the content uint256 filledAt; uint256 slotIndex; - /// @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 Host is slashed for missing a proof the slashed amount is reflected in this variable + /// @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.collateralPerByte * request.ask.slotSize + /// (== request.ask.collateralPerSlot() when using the AskHelpers library) + /// @dev When Host is slashed for missing a proof the slashed amount is + /// reflected in this variable uint256 currentCollateral; - address host; // address used for collateral interactions and identifying hosts + /// @notice address used for collateral interactions and identifying hosts + address host; } struct ActiveSlot { @@ -120,6 +127,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { return _token; } + function currentCollateral(SlotId slotId) public view returns (uint256) { + return _slots[slotId].currentCollateral; + } + function requestStorage(Request calldata request) public { RequestId id = request.id(); @@ -137,10 +148,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { if (request.ask.proofProbability == 0) { revert Marketplace_InsufficientProofProbability(); } - if (request.ask.collateral == 0) { + if (request.ask.collateralPerByte == 0) { revert Marketplace_InsufficientCollateral(); } - if (request.ask.reward == 0) { + if (request.ask.pricePerBytePerSecond == 0) { revert Marketplace_InsufficientReward(); } if (bytes(request.content.cid).length == 0) { @@ -205,20 +216,20 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { // Collect collateral uint256 collateralAmount; + uint256 collateralPerSlot = request.ask.collateralPerSlot(); if (slotState(slotId) == SlotState.Repair) { // Host is repairing a slot and is entitled for repair reward, so he gets "discounted collateral" // in this way he gets "physically" the reward at the end of the request when the full amount of collateral // is returned to him. collateralAmount = - request.ask.collateral - - ((request.ask.collateral * _config.collateral.repairRewardPercentage) / - 100); + collateralPerSlot - + ((collateralPerSlot * _config.collateral.repairRewardPercentage) / 100); } else { - collateralAmount = request.ask.collateral; + collateralAmount = collateralPerSlot; } _transferFrom(msg.sender, collateralAmount); _marketplaceTotals.received += collateralAmount; - slot.currentCollateral = request.ask.collateral; // Even if he has collateral discounted, he is operating with full collateral + slot.currentCollateral = collateralPerSlot; // Even if he has collateral discounted, he is operating with full collateral _addToMySlots(slot.host, slotId); @@ -326,7 +337,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { // TODO: Reward for validator that calls this function if (missingProofs(slotId) % _config.collateral.slashCriterion == 0) { - uint256 slashedAmount = (request.ask.collateral * + uint256 slashedAmount = (request.ask.collateralPerSlot() * _config.collateral.slashPercentage) / 100; slot.currentCollateral -= slashedAmount; if ( @@ -586,7 +597,9 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { Request storage request = _requests[requestId]; if (startingTimestamp >= endingTimestamp) revert Marketplace_StartNotBeforeExpiry(); - return (endingTimestamp - startingTimestamp) * request.ask.reward; + return + (endingTimestamp - startingTimestamp) * + request.ask.pricePerSlotPerSecond(); } function getHost(SlotId slotId) public view returns (address) { diff --git a/contracts/Requests.sol b/contracts/Requests.sol index 39ca1d3..103320f 100644 --- a/contracts/Requests.sol +++ b/contracts/Requests.sol @@ -17,8 +17,8 @@ struct Ask { uint256 slotSize; // amount of storage per slot (in number of bytes) uint256 duration; // how long content should be stored (in seconds) uint256 proofProbability; // how often storage proofs are required - uint256 reward; // amount of tokens paid per second per slot to hosts - uint256 collateral; // amount of tokens required to be deposited by the hosts in order to fill the slot + uint256 pricePerBytePerSecond; // amount of tokens paid per second per byte to hosts + uint256 collateralPerByte; // amount of tokens per byte required to be deposited by the hosts in order to fill the slot uint64 maxSlotLoss; // Max slots that can be lost without data considered to be lost } @@ -45,7 +45,21 @@ enum SlotState { Repair // when slot slot was forcible freed (host was kicked out from hosting the slot because of too many missed proofs) and needs to be repaired } +library AskHelpers { + function collateralPerSlot(Ask memory ask) internal pure returns (uint256) { + return ask.collateralPerByte * ask.slotSize; + } + + function pricePerSlotPerSecond( + Ask memory ask + ) internal pure returns (uint256) { + return ask.pricePerBytePerSecond * ask.slotSize; + } +} + library Requests { + using AskHelpers for Ask; + function id(Request memory request) internal pure returns (RequestId) { return RequestId.wrap(keccak256(abi.encode(request))); } @@ -76,6 +90,9 @@ library Requests { } function maxPrice(Request memory request) internal pure returns (uint256) { - return request.ask.slots * request.ask.duration * request.ask.reward; + return + request.ask.slots * + request.ask.duration * + request.ask.pricePerSlotPerSecond(); } } diff --git a/deploy/token.js b/deploy/token.js index 826fe72..727b238 100644 --- a/deploy/token.js +++ b/deploy/token.js @@ -1,16 +1,31 @@ -const MINTED_TOKENS = 1_000_000_000 +const MINTED_TOKENS = 1_000_000_000_000_000 -module.exports = async ({ deployments, getNamedAccounts, getUnnamedAccounts, network }) => { +module.exports = async ({ + deployments, + getNamedAccounts, + getUnnamedAccounts, + network, +}) => { const { deployer } = await getNamedAccounts() - const tokenDeployment = await deployments.deploy("TestToken", { from: deployer }) - const token = await hre.ethers.getContractAt("TestToken", tokenDeployment.address) + const tokenDeployment = await deployments.deploy("TestToken", { + from: deployer, + }) + const token = await hre.ethers.getContractAt( + "TestToken", + tokenDeployment.address + ) - const accounts = [...Object.values(await getNamedAccounts()), ...(await getUnnamedAccounts())] + const accounts = [ + ...Object.values(await getNamedAccounts()), + ...(await getUnnamedAccounts()), + ] if (network.tags.local) { for (const account of accounts) { console.log(`Minting ${MINTED_TOKENS} tokens to address ${account}`) - const transaction = await token.mint(account, MINTED_TOKENS, { from: deployer }) + const transaction = await token.mint(account, MINTED_TOKENS, { + from: deployer, + }) await transaction.wait() } console.log() diff --git a/test/Marketplace.test.js b/test/Marketplace.test.js index a997c94..7e8254f 100644 --- a/test/Marketplace.test.js +++ b/test/Marketplace.test.js @@ -23,7 +23,12 @@ const { waitUntilSlotFailed, patchOverloads, } = require("./marketplace") -const { maxPrice, payoutForDuration } = require("./price") +const { + maxPrice, + pricePerSlotPerSecond, + payoutForDuration, +} = require("./price") +const { collateralPerSlot } = require("./collateral") const { snapshot, revert, @@ -35,7 +40,7 @@ const { } = require("./evm") const { arrayify } = require("ethers/lib/utils") -const ACCOUNT_STARTING_BALANCE = 1_000_000_000 +const ACCOUNT_STARTING_BALANCE = 1_000_000_000_000_000 describe("Marketplace constructor", function () { let Marketplace, token, verifier, config @@ -257,14 +262,14 @@ describe("Marketplace", function () { }) it("is rejected when insufficient collateral", async function () { - request.ask.collateral = 0 + request.ask.collateralPerByte = 0 await expect(marketplace.requestStorage(request)).to.be.revertedWith( "Marketplace_InsufficientCollateral" ) }) it("is rejected when insufficient reward", async function () { - request.ask.reward = 0 + request.ask.pricePerBytePerSecond = 0 await expect(marketplace.requestStorage(request)).to.be.revertedWith( "Marketplace_InsufficientReward" ) @@ -284,7 +289,7 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + await token.approve(marketplace.address, collateralPerSlot(request)) }) it("emits event when slot is filled", async function () { @@ -315,10 +320,12 @@ describe("Marketplace", function () { await advanceTimeForNextBlock(config.proofs.period + 1) const startBalance = await token.balanceOf(host.address) + const collateral = collateralPerSlot(request) const discountedCollateral = - request.ask.collateral - - (request.ask.collateral * config.collateral.repairRewardPercentage) / - 100 + collateral - + Math.round( + (collateral * config.collateral.repairRewardPercentage) / 100 + ) await token.approve(marketplace.address, discountedCollateral) await marketplace.fillSlot(slot.request, slot.index, proof) const endBalance = await token.balanceOf(host.address) @@ -404,7 +411,7 @@ describe("Marketplace", function () { const lastSlot = request.ask.slots - 1 await token.approve( marketplace.address, - request.ask.collateral * lastSlot + collateralPerSlot(request) * lastSlot ) await token.approve(marketplace.address, maxPrice(request) * lastSlot) for (let i = 0; i <= lastSlot; i++) { @@ -432,7 +439,7 @@ describe("Marketplace", function () { }) it("is rejected when approved collateral is insufficient", async function () { - let insufficient = request.ask.collateral - 1 + let insufficient = collateralPerSlot(request) - 1 await token.approve(marketplace.address, insufficient) await marketplace.reserveSlot(slot.request, slot.index) await expect( @@ -441,12 +448,12 @@ describe("Marketplace", 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, collateralPerSlot(request) * 2) const startBalance = await token.balanceOf(host.address) await marketplace.reserveSlot(slot.request, slot.index) await marketplace.fillSlot(slot.request, slot.index, proof) const endBalance = await token.balanceOf(host.address) - expect(startBalance - endBalance).to.eq(request.ask.collateral) + expect(startBalance - endBalance).to.eq(collateralPerSlot(request)) }) }) @@ -456,7 +463,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) await marketplace.reserveSlot(slot.request, slot.index) await marketplace.fillSlot(slot.request, slot.index, proof) await advanceTimeForNextBlock(config.proofs.period) @@ -494,7 +502,8 @@ describe("Marketplace", function () { await marketplace.requestStorage(request) requestTime = await currentTime() switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("sets the request end time to now + duration", async function () { @@ -551,7 +560,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("fails to free slot when slot not filled", async function () { @@ -589,7 +599,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("finished request pays out reward based on time hosted", async function () { @@ -611,8 +622,9 @@ describe("Marketplace", function () { const endBalanceHost = await token.balanceOf(host.address) expect(expectedPayouts[slot.index]).to.be.lt(maxPrice(request)) + const collateral = collateralPerSlot(request) expect(endBalanceHost - startBalanceHost).to.equal( - expectedPayouts[slot.index] + request.ask.collateral + expectedPayouts[slot.index] + collateral ) }) @@ -625,6 +637,10 @@ describe("Marketplace", function () { hostCollateralRecipient.address ) + const collateralToBeReturned = await marketplace.currentCollateral( + slotId(slot) + ) + await marketplace.freeSlot( slotId(slot), hostRewardRecipient.address, @@ -638,8 +654,9 @@ describe("Marketplace", function () { const endBalanceHost = await token.balanceOf(host.address) expect(endBalanceHost).to.equal(startBalanceHost) expect(endBalanceCollateral - startBalanceCollateral).to.equal( - request.ask.collateral + collateralPerSlot(request) ) + expect(collateralToBeReturned).to.equal(collateralPerSlot(request)) }) it("pays reward to host reward address if specified", async function () { @@ -679,7 +696,8 @@ describe("Marketplace", function () { await waitUntilCancelled(request) await marketplace.freeSlot(slotId(slot)) - const expectedPartialPayout = (expiresAt - filledAt) * request.ask.reward + const expectedPartialPayout = + (expiresAt - filledAt) * pricePerSlotPerSecond(request) const endBalance = await token.balanceOf(host.address) expect(endBalance - ACCOUNT_STARTING_BALANCE).to.be.equal( expectedPartialPayout @@ -704,13 +722,19 @@ describe("Marketplace", function () { const startBalanceCollateral = await token.balanceOf( hostCollateralRecipient.address ) + + const collateralToBeReturned = await marketplace.currentCollateral( + slotId(slot) + ) + await marketplace.freeSlot( slotId(slot), hostRewardRecipient.address, hostCollateralRecipient.address ) - const expectedPartialPayout = (expiresAt - filledAt) * request.ask.reward + const expectedPartialPayout = + (expiresAt - filledAt) * pricePerSlotPerSecond(request) const endBalanceReward = await token.balanceOf( hostRewardRecipient.address @@ -726,8 +750,10 @@ describe("Marketplace", function () { hostCollateralRecipient.address ) expect(endBalanceCollateral - startBalanceCollateral).to.be.equal( - request.ask.collateral + collateralPerSlot(request) ) + + expect(collateralToBeReturned).to.be.equal(collateralPerSlot(request)) }) it("does not pay when the contract hasn't ended", async function () { @@ -777,21 +803,23 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("emits event when all slots are filled", async function () { const lastSlot = request.ask.slots - 1 await token.approve( marketplace.address, - request.ask.collateral * lastSlot + collateralPerSlot(request) * lastSlot ) for (let i = 0; i < lastSlot; i++) { await marketplace.reserveSlot(slot.request, i) await marketplace.fillSlot(slot.request, i, proof) } - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) await marketplace.reserveSlot(slot.request, lastSlot) await expect(marketplace.fillSlot(slot.request, lastSlot, proof)) .to.emit(marketplace, "RequestFulfilled") @@ -799,7 +827,8 @@ describe("Marketplace", function () { }) it("sets state when all slots are filled", async function () { const slots = request.ask.slots - await token.approve(marketplace.address, request.ask.collateral * slots) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral * slots) for (let i = 0; i < slots; i++) { await marketplace.reserveSlot(slot.request, i) await marketplace.fillSlot(slot.request, i, proof) @@ -812,7 +841,7 @@ describe("Marketplace", function () { const lastSlot = request.ask.slots - 1 await token.approve( marketplace.address, - request.ask.collateral * (lastSlot + 1) + collateralPerSlot(request) * (lastSlot + 1) ) for (let i = 0; i <= lastSlot; i++) { await marketplace.reserveSlot(slot.request, i) @@ -830,7 +859,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("rejects withdraw when request not yet timed out", async function () { @@ -852,7 +882,7 @@ describe("Marketplace", function () { const lastSlot = request.ask.slots - 1 await token.approve( marketplace.address, - request.ask.collateral * (lastSlot + 1) + collateralPerSlot(request) * (lastSlot + 1) ) for (let i = 0; i <= lastSlot; i++) { await marketplace.reserveSlot(slot.request, i) @@ -915,7 +945,7 @@ describe("Marketplace", function () { // at the time of expiry and hence the user would get the full "expiry window" reward back. expect(endBalancePayout - startBalancePayout).to.be.gt(0) expect(endBalancePayout - startBalancePayout).to.be.lte( - request.expiry * request.ask.reward + request.expiry * pricePerSlotPerSecond(request) ) }) @@ -974,7 +1004,7 @@ describe("Marketplace", function () { await marketplace.fillSlot(slot.request, slot.index, proof) await waitUntilCancelled(request) const expectedPartialhostRewardRecipient = - (expiresAt - filledAt) * request.ask.reward + (expiresAt - filledAt) * pricePerSlotPerSecond(request) switchAccount(client) await marketplace.withdrawFunds( @@ -1018,7 +1048,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("is 'New' initially", async function () { @@ -1056,7 +1087,7 @@ describe("Marketplace", 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) + collateralPerSlot(request) * (request.ask.maxSlotLoss + 1) ) for (let i = 0; i <= request.ask.maxSlotLoss; i++) { await marketplace.reserveSlot(slot.request, i) @@ -1098,7 +1129,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) async function waitUntilProofIsRequired(id) { @@ -1185,7 +1217,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) async function waitUntilProofWillBeRequired(id) { @@ -1276,7 +1309,8 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) async function waitUntilProofIsRequired(id) { @@ -1315,8 +1349,10 @@ describe("Marketplace", function () { await advanceTimeForNextBlock(period + 1) await marketplace.markProofAsMissing(id, missedPeriod) } - const expectedBalance = - (request.ask.collateral * (100 - slashPercentage)) / 100 + const collateral = collateralPerSlot(request) + const expectedBalance = Math.round( + (collateral * (100 - slashPercentage)) / 100 + ) expect( BigNumber.from(expectedBalance).eq( @@ -1327,9 +1363,10 @@ describe("Marketplace", function () { }) it("frees slot when collateral slashed below minimum threshold", async function () { + const collateral = collateralPerSlot(request) const minimum = - request.ask.collateral - - (request.ask.collateral * + collateral - + (collateral * config.collateral.maxNumberOfSlashes * config.collateral.slashPercentage) / 100 @@ -1352,9 +1389,10 @@ describe("Marketplace", function () { }) it("free slot when minimum reached and resets missed proof counter", async function () { + const collateral = collateralPerSlot(request) const minimum = - request.ask.collateral - - (request.ask.collateral * + collateral - + (collateral * config.collateral.maxNumberOfSlashes * config.collateral.slashPercentage) / 100 @@ -1386,7 +1424,8 @@ describe("Marketplace", function () { describe("list of active requests", function () { beforeEach(async function () { switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) switchAccount(client) await token.approve(marketplace.address, maxPrice(request)) }) @@ -1440,14 +1479,16 @@ describe("Marketplace", function () { await token.approve(marketplace.address, maxPrice(request)) await marketplace.requestStorage(request) switchAccount(host) - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) }) it("adds slot to list when filling slot", async function () { await marketplace.reserveSlot(slot.request, slot.index) await marketplace.fillSlot(slot.request, slot.index, proof) let slot1 = { ...slot, index: slot.index + 1 } - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) await marketplace.reserveSlot(slot.request, slot1.index) await marketplace.fillSlot(slot.request, slot1.index, proof) expect(await marketplace.mySlots()).to.have.members([ @@ -1460,10 +1501,11 @@ describe("Marketplace", function () { await marketplace.reserveSlot(slot.request, slot.index) await marketplace.fillSlot(slot.request, slot.index, proof) let slot1 = { ...slot, index: slot.index + 1 } - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) await marketplace.reserveSlot(slot.request, slot1.index) await marketplace.fillSlot(slot.request, slot1.index, proof) - await token.approve(marketplace.address, request.ask.collateral) + await token.approve(marketplace.address, collateral) await marketplace.freeSlot(slotId(slot)) expect(await marketplace.mySlots()).to.have.members([slotId(slot1)]) }) @@ -1473,7 +1515,8 @@ describe("Marketplace", function () { await marketplace.fillSlot(slot.request, slot.index, proof) let slot1 = { ...slot, index: slot.index + 1 } - await token.approve(marketplace.address, request.ask.collateral) + const collateral = collateralPerSlot(request) + await token.approve(marketplace.address, collateral) await marketplace.reserveSlot(slot.request, slot1.index) await marketplace.fillSlot(slot.request, slot1.index, proof) await waitUntilCancelled(request) diff --git a/test/collateral.js b/test/collateral.js new file mode 100644 index 0000000..ce60bf1 --- /dev/null +++ b/test/collateral.js @@ -0,0 +1,5 @@ +function collateralPerSlot(request) { + return request.ask.collateralPerByte * request.ask.slotSize +} + +module.exports = { collateralPerSlot } diff --git a/test/examples.js b/test/examples.js index ac88a71..ae5a955 100644 --- a/test/examples.js +++ b/test/examples.js @@ -29,9 +29,9 @@ const exampleRequest = async () => { slotSize: 1 * 1024 * 1024 * 1024, // 1 Gigabyte duration: hours(10), proofProbability: 4, // require a proof roughly once every 4 periods - reward: 84, + pricePerBytePerSecond: 1, maxSlotLoss: 2, - collateral: 200, + collateralPerByte: 1, }, content: { cid: "zb2rhheVmk3bLks5MgzTqyznLu1zqGH5jrfTA1eAZXrjx7Vob", diff --git a/test/ids.js b/test/ids.js index 5ef1220..af3dada 100644 --- a/test/ids.js +++ b/test/ids.js @@ -15,8 +15,8 @@ function askToArray(ask) { ask.slotSize, ask.duration, ask.proofProbability, - ask.reward, - ask.collateral, + ask.pricePerBytePerSecond, + ask.collateralPerByte, ask.maxSlotLoss, ] } diff --git a/test/marketplace.js b/test/marketplace.js index 218e6c3..5eaef19 100644 --- a/test/marketplace.js +++ b/test/marketplace.js @@ -1,6 +1,7 @@ const { advanceTimeToForNextBlock, currentTime } = require("./evm") const { slotId, requestId } = require("./ids") const { maxPrice, payoutForDuration } = require("./price") +const { collateralPerSlot } = require("./collateral") /** * @dev This will not advance the time right on the "expiry threshold" but will most probably "overshoot it" @@ -15,7 +16,8 @@ async function waitUntilCancelled(request) { } async function waitUntilSlotsFilled(contract, request, proof, token, slots) { - await token.approve(contract.address, request.ask.collateral * slots.length) + let collateral = collateralPerSlot(request) + await token.approve(contract.address, collateral * slots.length) let requestEnd = (await contract.requestEnd(requestId(request))).toNumber() const payouts = [] diff --git a/test/price.js b/test/price.js index 699204d..b4e0593 100644 --- a/test/price.js +++ b/test/price.js @@ -1,9 +1,15 @@ +function pricePerSlotPerSecond(request) { + return request.ask.pricePerBytePerSecond * request.ask.slotSize +} + function maxPrice(request) { - return request.ask.slots * request.ask.duration * request.ask.reward + return ( + request.ask.slots * request.ask.duration * pricePerSlotPerSecond(request) + ) } function payoutForDuration(request, start, end) { - return (end - start) * request.ask.reward + return (end - start) * pricePerSlotPerSecond(request) } -module.exports = { maxPrice, payoutForDuration } +module.exports = { maxPrice, pricePerSlotPerSecond, payoutForDuration }