mirror of
https://github.com/logos-storage/logos-storage-contracts-eth.git
synced 2026-01-03 13:53:10 +00:00
marketplace: transfer repair reward in vault
This commit is contained in:
parent
09a3cbcb09
commit
ab5dad67af
@ -147,10 +147,14 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
||||
|
||||
_addToMyRequests(request.client, id);
|
||||
|
||||
TokensPerSecond pricePerSecond = request.ask.pricePerSecond();
|
||||
uint128 price = pricePerSecond.accumulate(request.ask.duration);
|
||||
|
||||
FundId fund = id.asFundId();
|
||||
AccountId account = _vault.clientAccount(request.client);
|
||||
_vault.lock(fund, expiresAt, endsAt);
|
||||
_transferToVault(request.client, fund, account, request.maxPrice());
|
||||
_transferToVault(request.client, fund, account, price);
|
||||
_vault.flow(fund, account, account, pricePerSecond);
|
||||
|
||||
emit StorageRequested(id, request.ask, expiresAt);
|
||||
}
|
||||
@ -195,25 +199,23 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
||||
|
||||
context.slotsFilled += 1;
|
||||
|
||||
// Collect collateral
|
||||
uint128 collateralAmount = request.collateralPerSlot();
|
||||
uint128 designatedAmount = _config.collateral.designatedCollateral(
|
||||
collateralAmount
|
||||
);
|
||||
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 -= _config.collateral.repairReward(collateralAmount);
|
||||
}
|
||||
|
||||
FundId fund = requestId.asFundId();
|
||||
AccountId clientAccount = _vault.clientAccount(request.client);
|
||||
AccountId hostAccount = _vault.hostAccount(slot.host, slotIndex);
|
||||
TokensPerSecond rate = request.ask.pricePerSlotPerSecond();
|
||||
|
||||
_transferToVault(slot.host, fund, hostAccount, collateralAmount);
|
||||
_vault.designate(fund, hostAccount, designatedAmount);
|
||||
uint128 collateral = request.collateralPerSlot();
|
||||
uint128 designated = _config.collateral.designatedCollateral(collateral);
|
||||
|
||||
if (slotState(slotId) == SlotState.Repair) {
|
||||
// host gets a discount on its collateral, paid for by the repair reward
|
||||
uint128 repairReward = _config.collateral.repairReward(collateral);
|
||||
_vault.transfer(fund, clientAccount, hostAccount, repairReward);
|
||||
collateral -= repairReward;
|
||||
}
|
||||
|
||||
_transferToVault(slot.host, fund, hostAccount, collateral);
|
||||
_vault.designate(fund, hostAccount, designated);
|
||||
_vault.flow(fund, clientAccount, hostAccount, rate);
|
||||
|
||||
_addToMySlots(slot.host, slotId);
|
||||
@ -334,12 +336,15 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
|
||||
|
||||
Request storage request = _requests[requestId];
|
||||
|
||||
TokensPerSecond rate = request.ask.pricePerSlotPerSecond();
|
||||
uint128 collateral = request.collateralPerSlot();
|
||||
uint128 repairReward = _config.collateral.repairReward(collateral);
|
||||
|
||||
FundId fund = requestId.asFundId();
|
||||
AccountId hostAccount = _vault.hostAccount(slot.host, slot.slotIndex);
|
||||
AccountId clientAccount = _vault.clientAccount(request.client);
|
||||
TokensPerSecond rate = request.ask.pricePerSlotPerSecond();
|
||||
|
||||
_vault.flow(fund, hostAccount, clientAccount, rate);
|
||||
_vault.transfer(fund, hostAccount, clientAccount, repairReward);
|
||||
_vault.burnAccount(fund, hostAccount);
|
||||
|
||||
_removeFromMySlots(slot.host, slotId);
|
||||
|
||||
@ -49,12 +49,19 @@ enum SlotState {
|
||||
}
|
||||
|
||||
library AskHelpers {
|
||||
using AskHelpers for Ask;
|
||||
|
||||
function pricePerSlotPerSecond(
|
||||
Ask memory ask
|
||||
) internal pure returns (TokensPerSecond) {
|
||||
uint96 perByte = TokensPerSecond.unwrap(ask.pricePerBytePerSecond);
|
||||
return TokensPerSecond.wrap(perByte * ask.slotSize);
|
||||
}
|
||||
|
||||
function pricePerSecond(Ask memory ask) internal pure returns (TokensPerSecond) {
|
||||
uint96 perSlot = TokensPerSecond.unwrap(ask.pricePerSlotPerSecond());
|
||||
return TokensPerSecond.wrap(perSlot * ask.slots);
|
||||
}
|
||||
}
|
||||
|
||||
library Requests {
|
||||
@ -89,11 +96,4 @@ library Requests {
|
||||
result := ids
|
||||
}
|
||||
}
|
||||
|
||||
function maxPrice(Request memory request) internal pure returns (uint128) {
|
||||
uint64 slots = request.ask.slots;
|
||||
TokensPerSecond rate = request.ask.pricePerSlotPerSecond();
|
||||
Duration duration = request.ask.duration;
|
||||
return slots * rate.accumulate(duration);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ const {
|
||||
pricePerSlotPerSecond,
|
||||
payoutForDuration,
|
||||
} = require("./price")
|
||||
const { collateralPerSlot } = require("./collateral")
|
||||
const { collateralPerSlot, repairReward } = require("./collateral")
|
||||
const {
|
||||
snapshot,
|
||||
revert,
|
||||
@ -296,33 +296,39 @@ describe("Marketplace", function () {
|
||||
expect(await marketplace.getHost(slotId(slot))).to.equal(host.address)
|
||||
})
|
||||
|
||||
it("gives discount on the collateral for repaired slot", async function () {
|
||||
await marketplace.reserveSlot(slot.request, slot.index)
|
||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||
await marketplace.freeSlot(slotId(slot))
|
||||
expect(await marketplace.slotState(slotId(slot))).to.equal(
|
||||
SlotState.Repair
|
||||
)
|
||||
describe("when repairing a slot", function () {
|
||||
beforeEach(async function () {
|
||||
await marketplace.reserveSlot(slot.request, slot.index)
|
||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||
await advanceTime(config.proofs.period + 1)
|
||||
await marketplace.freeSlot(slotId(slot))
|
||||
})
|
||||
|
||||
// We need to advance the time to next period, because filling slot
|
||||
// must not be done in the same period as for that period there was already proof
|
||||
// submitted with the previous `fillSlot` and the transaction would revert with "Proof already submitted".
|
||||
await advanceTime(config.proofs.period + 1)
|
||||
it("gives the host a discount on the collateral", async function () {
|
||||
const collateral = collateralPerSlot(request)
|
||||
const reward = repairReward(config, collateral)
|
||||
const discountedCollateral = collateral - reward
|
||||
await token.approve(marketplace.address, discountedCollateral)
|
||||
|
||||
const startBalance = await token.balanceOf(host.address)
|
||||
const collateral = collateralPerSlot(request)
|
||||
const discountedCollateral =
|
||||
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)
|
||||
expect(startBalance - endBalance).to.equal(discountedCollateral)
|
||||
expect(await marketplace.slotState(slotId(slot))).to.equal(
|
||||
SlotState.Filled
|
||||
)
|
||||
const startBalance = await token.balanceOf(host.address)
|
||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||
const endBalance = await token.balanceOf(host.address)
|
||||
|
||||
expect(startBalance - endBalance).to.equal(discountedCollateral)
|
||||
})
|
||||
|
||||
it("tops up the host collateral with the repair reward", async function () {
|
||||
const collateral = collateralPerSlot(request)
|
||||
const reward = repairReward(config, collateral)
|
||||
const discountedCollateral = collateral - reward
|
||||
await token.approve(marketplace.address, discountedCollateral)
|
||||
|
||||
const startBalance = await marketplace.getSlotBalance(slotId(slot))
|
||||
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||
const endBalance = await marketplace.getSlotBalance(slotId(slot))
|
||||
|
||||
expect(endBalance - startBalance).to.equal(collateral)
|
||||
})
|
||||
})
|
||||
|
||||
it("fails to retrieve a request of an empty slot", async function () {
|
||||
@ -850,8 +856,9 @@ describe("Marketplace", function () {
|
||||
|
||||
const hostPayouts = payouts.reduce((a, b) => a + b, 0)
|
||||
const refund = payoutForDuration(request, freedAt, requestEnd)
|
||||
const reward = repairReward(config, collateralPerSlot(request))
|
||||
expect(endBalance - startBalance).to.equal(
|
||||
maxPrice(request) - hostPayouts + refund
|
||||
maxPrice(request) - hostPayouts + refund + reward
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -2,4 +2,9 @@ function collateralPerSlot(request) {
|
||||
return request.ask.collateralPerByte * request.ask.slotSize
|
||||
}
|
||||
|
||||
module.exports = { collateralPerSlot }
|
||||
function repairReward(configuration, collateral) {
|
||||
const percentage = configuration.collateral.repairRewardPercentage
|
||||
return Math.round((collateral * percentage) / 100)
|
||||
}
|
||||
|
||||
module.exports = { collateralPerSlot, repairReward }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user