diff --git a/contracts/BalanceTrackerFixedPriceBase.sol b/contracts/BalanceTrackerFixedPriceBase.sol index b64f4e8..9bc5c78 100644 --- a/contracts/BalanceTrackerFixedPriceBase.sol +++ b/contracts/BalanceTrackerFixedPriceBase.sol @@ -224,7 +224,8 @@ abstract contract BalanceTrackerFixedPriceBase { // Get mech balance uint256 balance = mapMechBalances[mech]; - if (balance == 0) { + // If balance is 1, the marketplace fee is still 1, and thus mech payment will be zero + if (balance < 2) { revert ZeroValue(); } diff --git a/contracts/OlasMech.sol b/contracts/OlasMech.sol index 1497bc6..273b404 100644 --- a/contracts/OlasMech.sol +++ b/contracts/OlasMech.sol @@ -223,7 +223,7 @@ abstract contract OlasMech is Mech, IErrorsMech, ImmutableStorage { function requestFromMarketplace(address requester, bytes memory data, uint256 requestId) external { // Check for marketplace access if (msg.sender != mechMarketplace) { - revert MarketplaceNotAuthorized(msg.sender); + revert MarketplaceOnly(msg.sender, mechMarketplace); } // Perform a request @@ -236,7 +236,7 @@ abstract contract OlasMech is Mech, IErrorsMech, ImmutableStorage { function revokeRequest(uint256 requestId) external { // Check for marketplace access if (msg.sender != mechMarketplace) { - revert MarketplaceNotAuthorized(msg.sender); + revert MarketplaceOnly(msg.sender, mechMarketplace); } address requester = mapRequestAddresses[requestId]; diff --git a/contracts/interfaces/IErrorsMech.sol b/contracts/interfaces/IErrorsMech.sol index e244c82..565aeb8 100644 --- a/contracts/interfaces/IErrorsMech.sol +++ b/contracts/interfaces/IErrorsMech.sol @@ -11,9 +11,10 @@ interface IErrorsMech { /// @dev The contract is already initialized. error AlreadyInitialized(); - /// @dev Mech marketplace is not authorized. - /// @param mechMarketplace Mech marketplace address. - error MarketplaceNotAuthorized(address mechMarketplace); + /// @dev Only `marketplace` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param marketplace Required marketplace address. + error MarketplaceOnly(address sender, address marketplace); /// @dev Request Id not found. /// @param requestId Request Id. diff --git a/test/MechFixedPriceNative.js b/test/MechFixedPriceNative.js index c4feb46..7aa735c 100644 --- a/test/MechFixedPriceNative.js +++ b/test/MechFixedPriceNative.js @@ -143,7 +143,7 @@ describe("MechFixedPriceNative", function () { // Try to post a request directly to the mech await expect( priorityMech.requestFromMarketplace(deployer.address, data, 0) - ).to.be.revertedWithCustomError(priorityMech, "MarketplaceNotAuthorized"); + ).to.be.revertedWithCustomError(priorityMech, "MarketplaceOnly"); // Response time is out of bounds await expect( @@ -224,6 +224,11 @@ describe("MechFixedPriceNative", function () { priorityMech.deliverToMarketplace(requestId, data) ).to.be.revertedWithCustomError(priorityMech, "RequestIdNotFound"); + // Try to check and record delivery rate not by marketplace + await expect( + balanceTrackerFixedPriceNative.checkAndRecordDeliveryRate(deployer.address, 0, "0x") + ).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "MarketplaceOnly"); + // Create a request await mechMarketplace.request(data, mechServiceId, requesterServiceId, minResponseTimeout, "0x", {value: maxDeliveryRate}); @@ -232,6 +237,11 @@ describe("MechFixedPriceNative", function () { priorityMech.connect(signers[1]).deliverToMarketplace(requestId, data) ).to.be.reverted; + // Try to finalize delivery rate not by marketplace + await expect( + balanceTrackerFixedPriceNative.finalizeDeliveryRate(priorityMech.address, deployer.address, 0, 0) + ).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "MarketplaceOnly"); + // Get the request status (requested priority) status = await mechMarketplace.getRequestStatus(requestId); expect(status).to.equal(1); @@ -302,6 +312,17 @@ describe("MechFixedPriceNative", function () { let mechBalance = await balanceTrackerFixedPriceNative.mapMechBalances(priorityMech.address); expect(mechBalance).to.equal(maxDeliveryRate); + // Try to collect fees before any payment processing + await expect( + balanceTrackerFixedPriceNative.drain() + ).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "ZeroValue"); + + // Try to process payment for mech not by its service multisig + await expect( + balanceTrackerFixedPriceNative.connect(signers[1]).processPaymentByMultisig(priorityMech.address) + ).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "UnauthorizedAccount"); + + const balanceBefore = await ethers.provider.getBalance(priorityMech.address); // Process payment for mech await balanceTrackerFixedPriceNative.processPaymentByMultisig(priorityMech.address); diff --git a/test/MechMarketplace.js b/test/MechMarketplace.js index b64661b..a1cc90c 100644 --- a/test/MechMarketplace.js +++ b/test/MechMarketplace.js @@ -57,6 +57,10 @@ describe("MechMarketplace", function () { const mechMarketplaceProxy = await MechMarketplaceProxy.deploy(mechMarketplace.address, proxyData); await mechMarketplaceProxy.deployed(); + // Get implementation + const implementation = await mechMarketplaceProxy.getImplementation(); + expect(implementation).to.equal(mechMarketplace.address); + mechMarketplace = await ethers.getContractAt("MechMarketplace", mechMarketplaceProxy.address); // Deploy mech factory @@ -148,7 +152,7 @@ describe("MechMarketplace", function () { ).to.be.revertedWithCustomError(mechMarketplace, "ZeroAddress"); // Changing the implementation - await mechMarketplace.connect(deployer).changeOwner(mechMarketplace.address); + await mechMarketplace.connect(deployer).changeImplementation(mechMarketplace.address); }); it("Change marketplace params", async function () { @@ -183,6 +187,9 @@ describe("MechMarketplace", function () { await expect( mechMarketplace.changeMarketplaceParams(10, 10, maxUint96) ).to.be.revertedWithCustomError(mechMarketplace, "Overflow"); + + // Change params + await mechMarketplace.changeMarketplaceParams(fee, minResponseTimeout, maxResponseTimeout); }); it("Factories and balance trackers", async function () {