Files
aitbc/contracts/test/TreasuryManager.test.js
aitbc 87e524e42c feat: enhance smart contract testing and deployment
- Add comprehensive test files for core contracts (ContractRegistry, TreasuryManager, AgentMarketplaceV2, EscrowService, DynamicPricing)
- Add Foundry fuzz tests for ContractRegistry, TreasuryManager, and AgentMarketplaceV2
- Add deployment automation scripts (deploy-automation.js, verify-deployment.js, monitor-contracts.js)
- Fix Hardhat/toolbox version compatibility in package.json
- Update smart-contract-tests.yml workflow to include deployment job
2026-04-29 10:44:40 +02:00

172 lines
6.7 KiB
JavaScript

import { expect } from "chai";
import hardhat from "hardhat";
const { ethers } = hardhat;
describe("TreasuryManager", function () {
let treasuryManager, aitbcToken, contractRegistry;
let deployer, user1, user2;
const INITIAL_BALANCE = ethers.parseEther("1000000");
const BUDGET_AMOUNT = ethers.parseEther("10000");
beforeEach(async function () {
[deployer, user1, user2] = await ethers.getSigners();
// Deploy AIToken
const AIToken = await ethers.getContractFactory("AIToken");
aitbcToken = await AIToken.deploy(INITIAL_BALANCE);
await aitbcToken.waitForDeployment();
// Deploy ContractRegistry
const ContractRegistry = await ethers.getContractFactory("ContractRegistry");
contractRegistry = await ContractRegistry.deploy();
await contractRegistry.waitForDeployment();
// Deploy TreasuryManager
const TreasuryManager = await ethers.getContractFactory("TreasuryManager");
treasuryManager = await TreasuryManager.deploy(await aitbcToken.getAddress());
await treasuryManager.waitForDeployment();
// Initialize treasury (this will register it in the registry)
await treasuryManager.initialize(await contractRegistry.getAddress());
// Transfer tokens to treasury
await aitbcToken.transfer(await treasuryManager.getAddress(), ethers.parseEther("100000"));
});
describe("Deployment", function () {
it("Should deploy with correct token address", async function () {
expect(await treasuryManager.treasuryToken()).to.equal(await aitbcToken.getAddress());
});
it("Should set deployer as owner", async function () {
expect(await treasuryManager.owner()).to.equal(deployer.address);
});
it("Should set registry address", async function () {
expect(await treasuryManager.registry()).to.equal(await contractRegistry.getAddress());
});
});
describe("Budget Category Management", function () {
it("Should create budget category", async function () {
await treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT);
const category = await treasuryManager.budgetCategories("operations");
expect(category.name).to.equal("operations");
expect(category.totalBudget).to.equal(BUDGET_AMOUNT);
expect(category.allocatedAmount).to.equal(0);
expect(category.spentAmount).to.equal(0);
expect(category.isActive).to.be.true;
});
it("Should emit BudgetCategoryCreated event", async function () {
await expect(
treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT)
).to.emit(treasuryManager, "BudgetCategoryCreated")
.withArgs("operations", BUDGET_AMOUNT, deployer.address);
});
it("Should revert if category already exists", async function () {
await treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT);
await expect(
treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT)
).to.be.revertedWith("Category already exists");
});
it("Should revert if non-owner creates category", async function () {
await expect(
treasuryManager.connect(user1).createBudgetCategory("operations", BUDGET_AMOUNT)
).to.be.revertedWithCustomError(treasuryManager, "NotAuthorized");
});
it("Should revert if budget amount is zero", async function () {
await expect(
treasuryManager.createBudgetCategory("operations", 0)
).to.be.revertedWithCustomError(treasuryManager, "InvalidAmount");
});
});
describe("Fund Allocation", function () {
beforeEach(async function () {
await treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT);
});
it("Should allocate funds", async function () {
await treasuryManager.allocateFunds("operations", user1.address, ethers.parseEther("1000"));
const category = await treasuryManager.budgetCategories("operations");
expect(category.allocatedAmount).to.equal(ethers.parseEther("1000"));
});
it("Should emit FundsAllocated event", async function () {
await expect(
treasuryManager.allocateFunds("operations", user1.address, ethers.parseEther("1000"))
).to.emit(treasuryManager, "FundsAllocated");
});
it("Should revert if insufficient budget", async function () {
await expect(
treasuryManager.allocateFunds("operations", user1.address, BUDGET_AMOUNT + ethers.parseEther("1"))
).to.be.revertedWithCustomError(treasuryManager, "InsufficientBudget");
});
it("Should revert if category is invalid", async function () {
await expect(
treasuryManager.allocateFunds("invalid", user1.address, ethers.parseEther("1000"))
).to.be.revertedWithCustomError(treasuryManager, "InvalidCategory");
});
});
describe("Treasury Operations", function () {
it("Should deposit funds to treasury", async function () {
const depositAmount = ethers.parseEther("1000");
await aitbcToken.mint(deployer.address, depositAmount);
await aitbcToken.approve(await treasuryManager.getAddress(), depositAmount);
await expect(
treasuryManager.depositFunds(depositAmount)
).to.emit(treasuryManager, "TreasuryDeposited");
});
it("Should emergency withdraw funds from treasury", async function () {
const withdrawAmount = ethers.parseEther("1000");
const initialBalance = await aitbcToken.balanceOf(deployer.address);
await treasuryManager.emergencyWithdraw(await aitbcToken.getAddress(), withdrawAmount);
const finalBalance = await aitbcToken.balanceOf(deployer.address);
expect(finalBalance - initialBalance).to.equal(withdrawAmount);
});
it("Should revert if non-owner withdraws", async function () {
await expect(
treasuryManager.connect(user1).emergencyWithdraw(await aitbcToken.getAddress(), ethers.parseEther("1000"))
).to.be.reverted;
});
it("Should revert if insufficient balance", async function () {
await expect(
treasuryManager.emergencyWithdraw(await aitbcToken.getAddress(), INITIAL_BALANCE + ethers.parseEther("1"))
).to.be.reverted;
});
});
describe("Treasury Status", function () {
it("Should get category count", async function () {
await treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT);
await treasuryManager.createBudgetCategory("development", BUDGET_AMOUNT);
expect(await treasuryManager.categoryCounter()).to.equal(2);
});
it("Should get allocation count", async function () {
await treasuryManager.createBudgetCategory("operations", BUDGET_AMOUNT);
await treasuryManager.allocateFunds("operations", user1.address, ethers.parseEther("1000"));
expect(await treasuryManager.allocationCounter()).to.equal(1);
});
});
});