Skip to content

Commit

Permalink
test: adding more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kupermind committed Dec 26, 2024
1 parent e653637 commit 8703480
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 1 deletion.
3 changes: 2 additions & 1 deletion contracts/test/ImportsSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
pragma solidity ^0.8.28;

// Getting required ABIs
import {MockServiceRegistry} from "../../lib/autonolas-registries/contracts/test/MockServiceRegistry.sol";
import {MockServiceRegistry} from "../../lib/autonolas-registries/contracts/test/MockServiceRegistry.sol";
import {ERC20Token} from "../../lib/autonolas-registries/contracts/test/ERC20Token.sol";
51 changes: 51 additions & 0 deletions test/MechFixedPriceNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,57 @@ describe("MechFixedPriceNative", function () {
expect(requesterBalance).to.equal(0);
});

it("Delivering a request by a priority mech with pre-paid logic with sufficient balance", 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});

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

// Try to withdraw mech zero balances
await expect(
balanceTrackerFixedPriceNative.withdraw()
).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "ZeroValue");

// Try to withdraw zero balances
await expect(
balanceTrackerFixedPriceNative.processPaymentByMultisig(priorityMech.address)
).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "ZeroValue");

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

// Check priority mech balance now
let mechBalance = await balanceTrackerFixedPriceNative.mapMechBalances(priorityMech.address);
expect(mechBalance).to.equal(maxDeliveryRate);

const balanceBefore = await ethers.provider.getBalance(priorityMech.address);
// Process payment for mech
await balanceTrackerFixedPriceNative.processPaymentByMultisig(priorityMech.address);
const balanceAfter = await ethers.provider.getBalance(priorityMech.address);

// Check charged fee
const collectedFees = await balanceTrackerFixedPriceNative.collectedFees();
// Since the delivery rate is smaller than MAX_FEE_FACTOR, the minimal fee was charged
expect(collectedFees).to.equal(1);

// Check mech payout: payment - fee
const balanceDiff = balanceAfter.sub(balanceBefore);
expect(balanceDiff).to.equal(maxDeliveryRate - 1);

// Check requester leftover balance
let requesterBalance = await balanceTrackerFixedPriceNative.mapRequesterBalances(deployer.address);
expect(requesterBalance).to.equal(0);

// Try to withdraw zero balances
await expect(
balanceTrackerFixedPriceNative.withdraw()
).to.be.revertedWithCustomError(balanceTrackerFixedPriceNative, "ZeroValue");
});

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
291 changes: 291 additions & 0 deletions test/MechFixedPriceToken.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
/*global describe, context, beforeEach, it*/

const { expect } = require("chai");
const { ethers } = require("hardhat");
const helpers = require("@nomicfoundation/hardhat-network-helpers");

describe("MechFixedPriceToken", function () {
let MechFixedPriceToken;

Check warning on line 8 in test/MechFixedPriceToken.js

View workflow job for this annotation

GitHub Actions / build

'MechFixedPriceToken' is assigned a value but never used
let priorityMechAddress;
let priorityMech;
let deliveryMechAddress;
let deliveryMech;
let serviceRegistry;
let mechMarketplace;
let token;
let karma;
let mechFactoryFixedPrice;
let balanceTrackerFixedPriceToken;
let signers;
let deployer;
const AddressZero = ethers.constants.AddressZero;

Check warning on line 21 in test/MechFixedPriceToken.js

View workflow job for this annotation

GitHub Actions / build

'AddressZero' is assigned a value but never used
const initMint = "1" + "0".repeat(25);
const maxDeliveryRate = 1000;
const data = "0x00";
const fee = 10;
const minResponseTimeout = 10;
const maxResponseTimeout = 20;
const mechServiceId = 1;
const requesterServiceId = 0;
const mechCreationData = ethers.utils.defaultAbiCoder.encode(["uint256"], [maxDeliveryRate]);

beforeEach(async function () {
signers = await ethers.getSigners();
deployer = signers[0];

const Token = await ethers.getContractFactory("ERC20Token");
token = await Token.deploy();
await token.deployed();

// Karma implementation and proxy
const Karma = await ethers.getContractFactory("Karma");
const karmaImplementation = await Karma.deploy();
await karmaImplementation.deployed();

// Initialize karma
let proxyData = karmaImplementation.interface.encodeFunctionData("initialize", []);
const KarmaProxy = await ethers.getContractFactory("KarmaProxy");
const karmaProxy = await KarmaProxy.deploy(karmaImplementation.address, proxyData);
await karmaProxy.deployed();

karma = await ethers.getContractAt("Karma", karmaProxy.address);

const ServiceRegistry = await ethers.getContractFactory("MockServiceRegistry");
serviceRegistry = await ServiceRegistry.deploy();
await serviceRegistry.deployed();

// Wrapped native token and buy back burner are not relevant for now
const MechMarketplace = await ethers.getContractFactory("MechMarketplace");
mechMarketplace = await MechMarketplace.deploy(serviceRegistry.address, karma.address);
await mechMarketplace.deployed();

// Deploy and initialize marketplace proxy
proxyData = MechMarketplace.interface.encodeFunctionData("initialize",
[fee, minResponseTimeout, maxResponseTimeout]);
const MechMarketplaceProxy = await ethers.getContractFactory("MechMarketplaceProxy");
const mechMarketplaceProxy = await MechMarketplaceProxy.deploy(mechMarketplace.address, proxyData);
await mechMarketplaceProxy.deployed();

mechMarketplace = await ethers.getContractAt("MechMarketplace", mechMarketplaceProxy.address);

// Deploy mech factory
const MechFactoryFixedPrice = await ethers.getContractFactory("MechFactoryFixedPriceToken");
mechFactoryFixedPrice = await MechFactoryFixedPrice.deploy(mechMarketplace.address);
await mechFactoryFixedPrice.deployed();

// Whitelist mech factory
await mechMarketplace.setMechFactoryStatuses([mechFactoryFixedPrice.address], [true]);

// Whitelist marketplace in the karma proxy
await karma.setMechMarketplaceStatuses([mechMarketplace.address], [true]);

// Pseudo-create two services
await serviceRegistry.setServiceOwner(mechServiceId, deployer.address);
await serviceRegistry.setServiceOwner(mechServiceId + 1, deployer.address);

// Pseudo-create a requester service
await serviceRegistry.setServiceOwner(requesterServiceId + 3, signers[1].address);

MechFixedPriceToken = await ethers.getContractFactory("MechFixedPriceToken");
// Create default priority mech
let tx = await mechMarketplace.create(mechServiceId, mechFactoryFixedPrice.address, mechCreationData);
let res = await tx.wait();
// Get mech contract address from the event
priorityMechAddress = "0x" + res.logs[0].topics[1].slice(26);
// Get mech contract instance
priorityMech = await ethers.getContractAt("MechFixedPriceToken", priorityMechAddress);

// Create default delivery mech
tx = await mechMarketplace.create(mechServiceId + 1, mechFactoryFixedPrice.address, mechCreationData);
res = await tx.wait();
// Get mech contract address from the event
deliveryMechAddress = "0x" + res.logs[0].topics[1].slice(26);
// Get mech contract instance
deliveryMech = await ethers.getContractAt("MechFixedPriceToken", deliveryMechAddress);

// Deploy
const BalanceTrackerFixedPriceToken = await ethers.getContractFactory("BalanceTrackerFixedPriceToken");
balanceTrackerFixedPriceToken = await BalanceTrackerFixedPriceToken.deploy(mechMarketplace.address,
deployer.address, token.address);
await balanceTrackerFixedPriceToken.deployed();

// Whitelist balance tracker
const paymentTypeHash = await priorityMech.paymentType();
await mechMarketplace.setPaymentTypeBalanceTrackers([paymentTypeHash], [balanceTrackerFixedPriceToken.address]);

// Mint tokens
await token.mint(deployer.address, initMint);
});

context("Deliver", async function () {
it("Delivering a request by a priority mech", async function () {
const requestId = await mechMarketplace.getRequestId(deployer.address, data, 0);

// Try to create a request without any tokens approved
await expect(
mechMarketplace.request(data, mechServiceId, requesterServiceId, minResponseTimeout, "0x")
).to.be.reverted;

// Approve tokens to post a request
await token.approve(balanceTrackerFixedPriceToken.address, maxDeliveryRate);

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

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

Check failure on line 135 in test/MechFixedPriceToken.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 142 in test/MechFixedPriceToken.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 priority mech with pre-paid logic", async function () {
// Get request Id
const requestId = await mechMarketplace.getRequestId(deployer.address, data, 0);

// Approve tokens to post a request
await token.approve(balanceTrackerFixedPriceToken.address, maxDeliveryRate - 1);

// Pre-pay the contract insufficient amount for posting a request
await balanceTrackerFixedPriceToken.deposit(maxDeliveryRate - 1);

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

// Approve more tokens
await token.approve(balanceTrackerFixedPriceToken.address, maxDeliveryRate);

// Pre-pay the contract more for posting a request
await balanceTrackerFixedPriceToken.deposit(maxDeliveryRate);

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

// Get the request status (requested priority)
let status = await mechMarketplace.getRequestStatus(requestId);
expect(status).to.equal(1);

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

// Get the request status (delivered)
status = await mechMarketplace.getRequestStatus(requestId);
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);

// Check priority mech balance now
let mechBalance = await balanceTrackerFixedPriceToken.mapMechBalances(priorityMech.address);
expect(mechBalance).to.equal(maxDeliveryRate);

const balanceBefore = await token.balanceOf(priorityMech.address);
// Process payment for mech
await balanceTrackerFixedPriceToken.processPaymentByMultisig(priorityMech.address);
const balanceAfter = await token.balanceOf(priorityMech.address);

// Check charged fee
let collectedFees = await balanceTrackerFixedPriceToken.collectedFees();
// Since the delivery rate is smaller than MAX_FEE_FACTOR, the minimal fee was charged
expect(collectedFees).to.equal(1);

// Drain funds to a buy back burner mock
await balanceTrackerFixedPriceToken.drain();
collectedFees = await balanceTrackerFixedPriceToken.collectedFees();
expect(collectedFees).to.equal(0);

// Check mech payout: payment - fee
const balanceDiff = balanceAfter.sub(balanceBefore);
expect(balanceDiff).to.equal(maxDeliveryRate - 1);

// Check requester leftover balance
let requesterBalance = await balanceTrackerFixedPriceToken.mapRequesterBalances(deployer.address);
expect(requesterBalance).to.equal(maxDeliveryRate - 1);

// Withdraw requester balances
await balanceTrackerFixedPriceToken.withdraw();
requesterBalance = await balanceTrackerFixedPriceToken.mapRequesterBalances(deployer.address);
expect(requesterBalance).to.equal(0);
});

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();

const requestId = await mechMarketplace.getRequestId(deployer.address, data, 0);

// Approve tokens to post a request
await token.approve(balanceTrackerFixedPriceToken.address, maxDeliveryRate);

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

// Try to deliver by a delivery mech right away
await expect(
deliveryMech.deliverToMarketplace(requestId, data)
).to.be.revertedWithCustomError(mechMarketplace, "PriorityMechResponseTimeout");

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

Check failure on line 252 in test/MechFixedPriceToken.js

View workflow job for this annotation

GitHub Actions / build

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

// Increase the time such that the request expires for a priority mech
await helpers.time.increase(maxResponseTimeout);

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

Check failure on line 259 in test/MechFixedPriceToken.js

View workflow job for this annotation

GitHub Actions / build

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

// Try to deliver by a mech with bigger max Delivery rate
await deliveryMech.changeMaxDeliveryRate(maxDeliveryRate + 1);
await expect(
deliveryMech.deliverToMarketplace(requestId, data)
).to.be.revertedWithCustomError(mechMarketplace, "Overflow");

// Change max delivery rate back
await deliveryMech.changeMaxDeliveryRate(maxDeliveryRate);

// Deliver a request by the delivery mech
await deliveryMech.deliverToMarketplace(requestId, data);

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

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

Check failure on line 278 in test/MechFixedPriceToken.js

View workflow job for this annotation

GitHub Actions / build

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

// Check priority mech and delivery mech karma
let mechKarma = await karma.mapMechKarma(priorityMech.address);
expect(mechKarma).to.equal(-1);
mechKarma = await karma.mapMechKarma(deliveryMech.address);
expect(mechKarma).to.equal(1);

// Restore a previous state of blockchain
snapshot.restore();
});
});
});

0 comments on commit 8703480

Please sign in to comment.