Skip to content

Commit

Permalink
fix: delivery recording bug
Browse files Browse the repository at this point in the history
  • Loading branch information
kupermind committed Dec 26, 2024
1 parent 5c3350b commit 0a3e4b7
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 19 deletions.
7 changes: 3 additions & 4 deletions contracts/BalanceTrackerFixedPriceBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ abstract contract BalanceTrackerFixedPriceBase {

// Check and record delivery rate
function checkAndRecordDeliveryRate(
address mech,
address requester,
uint256 maxDeliveryRate,
bytes memory
) external payable {
// Reentrancy guard
Expand All @@ -109,9 +109,6 @@ abstract contract BalanceTrackerFixedPriceBase {
// Get account balance
uint256 balance = mapRequesterBalances[requester] + initAmount;

// Get mech max delivery rate
uint256 maxDeliveryRate = IMech(mech).maxDeliveryRate();

// Check the request delivery rate for a fixed price
if (balance < maxDeliveryRate) {
// Get balance difference
Expand Down Expand Up @@ -150,12 +147,14 @@ abstract contract BalanceTrackerFixedPriceBase {
revert ZeroValue();
}

// Check for delivery rate difference
uint256 rateDiff;
if (maxDeliveryRate > actualDeliveryRate) {
// Return back requester overpayment debit
rateDiff = maxDeliveryRate - actualDeliveryRate;
mapRequesterBalances[requester] += rateDiff;
} else {
// Limit the rate by the max chosen one as that is what the requester agreed on
actualDeliveryRate = maxDeliveryRate;
}

Expand Down
19 changes: 10 additions & 9 deletions contracts/MechMarketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -381,13 +381,6 @@ contract MechMarketplace is IErrorsMarketplace {
// Get the request Id
requestId = getRequestId(msg.sender, data, mapNonces[msg.sender]);

// Get balance tracker address
bytes32 mechPaymentType = IMech(priorityMech).paymentType();
address balanceTracker = mapPaymentTypeBalanceTrackers[mechPaymentType];

// Check and record mech delivery rate
IBalanceTracker(balanceTracker).checkAndRecordDeliveryRate{value: msg.value}(priorityMech, msg.sender, paymentData);

// Update requester nonce
mapNonces[msg.sender]++;

Expand All @@ -400,8 +393,16 @@ contract MechMarketplace is IErrorsMarketplace {
mechDelivery.responseTimeout = responseTimeout + block.timestamp;
// Record request account
mechDelivery.requester = msg.sender;
// Record deliveryRate for request
mechDelivery.deliveryRate = msg.value;
// Record deliveryRate for request as priority mech max delivery rate
mechDelivery.deliveryRate = IMech(priorityMech).maxDeliveryRate();

// Get balance tracker address
bytes32 mechPaymentType = IMech(priorityMech).paymentType();
address balanceTracker = mapPaymentTypeBalanceTrackers[mechPaymentType];

// Check and record mech delivery rate
IBalanceTracker(balanceTracker).checkAndRecordDeliveryRate{value: msg.value}(msg.sender,
mechDelivery.deliveryRate, paymentData);

// Increase mech requester karma
IKarma(karma).changeRequesterMechKarma(msg.sender, priorityMech, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,15 @@ contract BalanceTrackerNvmSubscription {

// Check and record delivery rate
function checkAndRecordDeliveryRate(
address mech,
address requester,
uint256,
uint256 maxDeliveryRate,
bytes memory
) external payable {
// Check for marketplace access
if (msg.sender != mechMarketplace) {
revert MarketplaceOnly(msg.sender, mechMarketplace);
}

// Get mech max delivery rate
uint256 maxDeliveryRate = IMech(mech).maxDeliveryRate();

// Check that there is no incoming deposit
if (msg.value > 0) {
revert NoDepositAllowed(msg.value);
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/IBalanceTracker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity ^0.8.28;
interface IBalanceTracker {
// Check and record delivery rate
/// @param paymentData Additional payment-related request data, if applicable.
function checkAndRecordDeliveryRate(address mech, address requester, bytes memory paymentData) external payable;
function checkAndRecordDeliveryRate(address requester, uint256 maxDeliveryRate, bytes memory paymentData) external payable;

/// @dev Finalizes mech delivery rate based on requested and actual ones.
/// @param mech Delivery mech address.
Expand Down
40 changes: 40 additions & 0 deletions test/MechFixedPriceNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,46 @@ describe("MechFixedPriceNative", function () {
expect(mechKarma).to.equal(1);
});

it("Delivering a request by a priority mech with pre-paid logic", async function () {
// Get request Id
const requestId = await mechMarketplace.getRequestId(deployer.address, data, 0);

// Pre-pay the contract insufficient amount for posting a request
await deployer.sendTransaction({to: balanceTrackerFixedPriceNative.address, value: maxDeliveryRate - 1});

// Try to create request with insufficient pre-paid amount
await expect(
mechMarketplace.request(data, mechServiceId, requesterServiceId, minResponseTimeout, "0x")
).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "InsufficientBalance");

// Pre-pay the contract more for posting a request
await deployer.sendTransaction({to: balanceTrackerFixedPriceNative.address, value: maxDeliveryRate});

// Post a request
await mechMarketplace.request(data, mechServiceId, requesterServiceId, minResponseTimeout, "0x");

// Get the request status (requested priority)
status = await mechMarketplace.getRequestStatus(requestId);

Check failure on line 281 in test/MechFixedPriceNative.js

View workflow job for this annotation

GitHub Actions / build

Read-only global 'status' should not be modified
expect(status).to.equal(1);

// Deliver a request
await priorityMech.deliverToMarketplace(requestId, data);

// Get the request status (delivered)
status = await mechMarketplace.getRequestStatus(requestId);

Check failure on line 288 in test/MechFixedPriceNative.js

View workflow job for this annotation

GitHub Actions / build

Read-only global 'status' should not be modified
expect(status).to.equal(3);

// Try to deliver the same request again
await priorityMech.deliverToMarketplace(requestId, data);

// Check mech karma
let mechKarma = await karma.mapMechKarma(priorityMech.address);
expect(mechKarma).to.equal(1);
// Check requester mech karma
mechKarma = await karma.mapRequesterMechKarma(deployer.address, priorityMech.address);
expect(mechKarma).to.equal(1);
});

it("Delivering a request by a different mech", async function () {
// Take a snapshot of the current state of the blockchain
const snapshot = await helpers.takeSnapshot();
Expand Down

0 comments on commit 0a3e4b7

Please sign in to comment.