2024-03-05 21:21:27 -06:00
|
|
|
const {
|
2024-03-10 11:55:59 -05:00
|
|
|
time,
|
2024-03-05 21:21:27 -06:00
|
|
|
loadFixture,
|
|
|
|
} = require('@nomicfoundation/hardhat-toolbox/network-helpers');
|
|
|
|
const { expect } = require('chai');
|
|
|
|
const { ethers } = require('hardhat');
|
|
|
|
|
2024-03-06 16:57:09 -06:00
|
|
|
describe('DAO', () => {
|
2024-03-10 22:29:51 -05:00
|
|
|
async function deploy() {
|
2024-03-05 21:21:27 -06:00
|
|
|
const [account1, account2] = await ethers.getSigners();
|
|
|
|
const DAO = await ethers.getContractFactory('DAO');
|
|
|
|
const dao = await DAO.deploy();
|
|
|
|
return { dao, account1, account2 };
|
|
|
|
}
|
|
|
|
|
2024-03-10 11:55:59 -05:00
|
|
|
it('Should deploy', async () => {
|
2024-03-10 22:29:51 -05:00
|
|
|
const { dao } = await loadFixture(deploy);
|
2024-03-10 11:55:59 -05:00
|
|
|
expect(dao).to.exist;
|
2024-03-11 13:39:56 -05:00
|
|
|
expect(await dao.totalSupply()).to.equal(0);
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
|
|
|
|
2024-03-12 14:10:06 -05:00
|
|
|
describe('Post', () => {
|
|
|
|
it('should be able to add a post', async () => {
|
|
|
|
const { dao, account1 } = await loadFixture(deploy);
|
2024-03-12 18:02:07 -05:00
|
|
|
await expect(dao.addPost(account1)).to.emit(dao, 'PostAdded').withArgs(0);
|
2024-03-12 14:10:06 -05:00
|
|
|
const post = await dao.posts(0);
|
|
|
|
expect(post.author).to.equal(account1);
|
|
|
|
expect(post.sender).to.equal(account1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should be able to add a post on behalf of another account', async () => {
|
|
|
|
const { dao, account1, account2 } = await loadFixture(deploy);
|
|
|
|
await dao.addPost(account2);
|
|
|
|
const post = await dao.posts(0);
|
|
|
|
expect(post.author).to.equal(account2);
|
|
|
|
expect(post.sender).to.equal(account1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-03-05 21:21:27 -06:00
|
|
|
describe('Validation Pool', () => {
|
2024-03-10 11:55:59 -05:00
|
|
|
let dao;
|
|
|
|
let account1;
|
|
|
|
const POOL_DURATION = 3600; // 1 hour
|
2024-03-11 13:39:56 -05:00
|
|
|
const POOL_FEE = 100;
|
2024-03-10 11:55:59 -05:00
|
|
|
|
|
|
|
beforeEach(async () => {
|
2024-03-10 22:29:51 -05:00
|
|
|
const setup = await loadFixture(deploy);
|
2024-03-10 11:55:59 -05:00
|
|
|
dao = setup.dao;
|
|
|
|
account1 = setup.account1;
|
2024-03-12 14:10:06 -05:00
|
|
|
await dao.addPost(account1);
|
|
|
|
const init = () => dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
2024-03-10 11:55:59 -05:00
|
|
|
await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(0);
|
|
|
|
expect(await dao.validationPoolCount()).to.equal(1);
|
2024-03-10 12:57:30 -05:00
|
|
|
expect(await dao.memberCount()).to.equal(0);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(0);
|
2024-03-11 13:39:56 -05:00
|
|
|
expect(await dao.totalSupply()).to.equal(POOL_FEE);
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
describe('Initiate', () => {
|
|
|
|
it('should not be able to initiate a validation pool without a fee', async () => {
|
|
|
|
const setup = await loadFixture(deploy);
|
2024-03-12 14:10:06 -05:00
|
|
|
const init = () => setup.dao.initiateValidationPool(0, POOL_DURATION);
|
2024-03-11 13:39:56 -05:00
|
|
|
await expect(init()).to.be.revertedWith('Fee is required to initiate validation pool');
|
|
|
|
});
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-13 12:02:08 -05:00
|
|
|
it('should not be able to initiate a validation pool with duration below minimum', async () => {
|
|
|
|
const setup = await loadFixture(deploy);
|
|
|
|
const init = () => setup.dao.initiateValidationPool(0, 59, { value: POOL_FEE });
|
|
|
|
await expect(init()).to.be.revertedWith('Duration is too short');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not be able to initiate a validation pool with duration above maximum', async () => {
|
|
|
|
const setup = await loadFixture(deploy);
|
|
|
|
const init = () => setup.dao.initiateValidationPool(0, 86401, { value: POOL_FEE });
|
|
|
|
await expect(init()).to.be.revertedWith('Duration is too long');
|
|
|
|
});
|
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
it('should be able to initiate a second validation pool', async () => {
|
2024-03-12 14:10:06 -05:00
|
|
|
const init = () => dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
2024-03-11 13:39:56 -05:00
|
|
|
await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
|
|
|
|
expect(await dao.validationPoolCount()).to.equal(2);
|
|
|
|
});
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
it('Should be able to fetch pool instance', async () => {
|
|
|
|
const pool = await dao.validationPools(0);
|
|
|
|
expect(pool).to.exist;
|
|
|
|
expect(pool.duration).to.equal(POOL_DURATION);
|
2024-03-12 17:53:04 -05:00
|
|
|
expect(pool.postIndex).to.equal(0);
|
|
|
|
expect(pool.resolved).to.be.false;
|
2024-03-11 13:39:56 -05:00
|
|
|
});
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
describe('Evaluate outcome', () => {
|
|
|
|
it('should not be able to evaluate outcome before duration has elapsed', async () => {
|
|
|
|
await expect(dao.evaluateOutcome(0)).to.be.revertedWith('Pool end time has not yet arrived');
|
|
|
|
});
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
it('should be able to evaluate outcome after duration has elapsed', async () => {
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true);
|
|
|
|
expect(await dao.memberCount()).to.equal(1);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(100);
|
2024-03-12 17:53:04 -05:00
|
|
|
const pool = await dao.validationPools(0);
|
|
|
|
expect(pool.resolved).to.be.true;
|
|
|
|
expect(pool.outcome).to.be.true;
|
2024-03-11 13:39:56 -05:00
|
|
|
});
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
it('should not be able to evaluate outcome more than once', async () => {
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true);
|
|
|
|
await expect(dao.evaluateOutcome(0)).to.be.revertedWith('Pool is already resolved');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should be able to evaluate outcome of second validation pool', async () => {
|
2024-03-12 14:10:06 -05:00
|
|
|
const init = () => dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
2024-03-11 13:39:56 -05:00
|
|
|
await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
|
|
|
|
expect(await dao.validationPoolCount()).to.equal(2);
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(100);
|
|
|
|
await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, true);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(200);
|
|
|
|
});
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
|
|
|
|
2024-03-11 13:39:56 -05:00
|
|
|
describe('Stake', async () => {
|
|
|
|
beforeEach(async () => {
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await dao.evaluateOutcome(0);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(100);
|
|
|
|
expect(await dao.balanceOf(dao.target)).to.equal(0);
|
2024-03-12 14:10:06 -05:00
|
|
|
await dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
2024-03-11 13:39:56 -05:00
|
|
|
expect(await dao.balanceOf(dao.target)).to.equal(100);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should be able to stake before validation pool has elapsed', async () => {
|
|
|
|
await dao.stake(1, 10, true);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(90);
|
|
|
|
expect(await dao.balanceOf(dao.target)).to.equal(110);
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, true);
|
|
|
|
expect(await dao.balanceOf(dao.target)).to.equal(0);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(200);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not be able to stake after validation pool has elapsed', async () => {
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await expect(dao.stake(1, 10, true)).to.be.revertedWith('Pool end time has passed');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should be able to stake against a validation pool', async () => {
|
|
|
|
await dao.stake(1, 10, false);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(90);
|
|
|
|
expect(await dao.balanceOf(dao.target)).to.equal(110);
|
|
|
|
time.increase(POOL_DURATION + 1);
|
|
|
|
await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, false);
|
|
|
|
expect(await dao.balanceOf(dao.target)).to.equal(0);
|
|
|
|
expect(await dao.balanceOf(account1)).to.equal(200);
|
2024-03-12 17:53:04 -05:00
|
|
|
const pool = await dao.validationPools(1);
|
|
|
|
expect(pool.outcome).to.be.false;
|
2024-03-11 13:39:56 -05:00
|
|
|
});
|
2024-03-05 21:21:27 -06:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|