started on tests for lightweight bench
This commit is contained in:
		
							parent
							
								
									da20410f87
								
							
						
					
					
						commit
						3c4a5cbb7a
					
				| 
						 | 
				
			
			@ -28,7 +28,7 @@ if (ENABLE_STAKING === 'false') {
 | 
			
		|||
const start = async () => {
 | 
			
		||||
  dao.on('ValidationPoolInitiated', async (poolIndex) => {
 | 
			
		||||
    console.log('Validation Pool Initiated, index', poolIndex);
 | 
			
		||||
    const pool = await dao.validationPools(poolIndex);
 | 
			
		||||
    const pool = await dao.getValidationPool(poolIndex);
 | 
			
		||||
    // Read post from database
 | 
			
		||||
    let post;
 | 
			
		||||
    try {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,16 +4,16 @@ pragma solidity ^0.8.24;
 | 
			
		|||
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
 | 
			
		||||
import "./Reputation.sol";
 | 
			
		||||
import "./Bench.sol";
 | 
			
		||||
import "./LightweightBench.sol";
 | 
			
		||||
import "../GlobalForum.sol";
 | 
			
		||||
import "../interfaces/IAcceptAvailability.sol";
 | 
			
		||||
import "../interfaces/IOnValidate.sol";
 | 
			
		||||
 | 
			
		||||
import "hardhat/console.sol";
 | 
			
		||||
 | 
			
		||||
contract DAO {
 | 
			
		||||
    Reputation rep;
 | 
			
		||||
    GlobalForum forum;
 | 
			
		||||
    Bench bench;
 | 
			
		||||
    LightweightBench lightweightBench;
 | 
			
		||||
    mapping(uint => address) public members;
 | 
			
		||||
    uint public memberCount;
 | 
			
		||||
    mapping(address => bool) public isMember;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,16 +31,28 @@ contract DAO {
 | 
			
		|||
        bool votePasses,
 | 
			
		||||
        bool quorumMet
 | 
			
		||||
    );
 | 
			
		||||
    event LWResultProposed(
 | 
			
		||||
        uint poolIndex,
 | 
			
		||||
        uint proposedResultIndex,
 | 
			
		||||
        string proposedResultHash
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    constructor(Reputation reputation_, Bench bench_, GlobalForum forum_) {
 | 
			
		||||
    constructor(
 | 
			
		||||
        Reputation reputation_,
 | 
			
		||||
        Bench bench_,
 | 
			
		||||
        LightweightBench lightweightBench_,
 | 
			
		||||
        GlobalForum forum_
 | 
			
		||||
    ) {
 | 
			
		||||
        rep = reputation_;
 | 
			
		||||
        bench = bench_;
 | 
			
		||||
        lightweightBench = lightweightBench_;
 | 
			
		||||
        forum = forum_;
 | 
			
		||||
        rep.registerDAO(this);
 | 
			
		||||
        bench.registerDAO(this, forum);
 | 
			
		||||
        lightweightBench.registerDAO(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function emitPostAdded(string memory id) public {
 | 
			
		||||
    function emitPostAdded(string calldata id) public {
 | 
			
		||||
        emit PostAdded(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,9 +72,22 @@ contract DAO {
 | 
			
		|||
        emit LWValidationPoolInitiated(poolIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function emitLWResultProposed(
 | 
			
		||||
        uint poolIndex,
 | 
			
		||||
        uint proposedResultIndex,
 | 
			
		||||
        string calldata proposedResultHash
 | 
			
		||||
    ) public {
 | 
			
		||||
        emit LWResultProposed(
 | 
			
		||||
            poolIndex,
 | 
			
		||||
            proposedResultIndex,
 | 
			
		||||
            proposedResultHash
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function update(address from, address to, uint256 value) public {
 | 
			
		||||
        require(
 | 
			
		||||
            msg.sender == address(bench),
 | 
			
		||||
            msg.sender == address(lightweightBench) ||
 | 
			
		||||
                msg.sender == address(bench),
 | 
			
		||||
            "Only DAO core contracts may call update"
 | 
			
		||||
        );
 | 
			
		||||
        rep.update(from, to, value);
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +95,8 @@ contract DAO {
 | 
			
		|||
 | 
			
		||||
    function mint(address account, uint256 value) public {
 | 
			
		||||
        require(
 | 
			
		||||
            msg.sender == address(bench),
 | 
			
		||||
            msg.sender == address(lightweightBench) ||
 | 
			
		||||
                msg.sender == address(bench),
 | 
			
		||||
            "Only DAO core contracts may call mint"
 | 
			
		||||
        );
 | 
			
		||||
        rep.mint(account, value);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +104,8 @@ contract DAO {
 | 
			
		|||
 | 
			
		||||
    function burn(address account, uint256 value) public {
 | 
			
		||||
        require(
 | 
			
		||||
            msg.sender == address(bench),
 | 
			
		||||
            msg.sender == address(lightweightBench) ||
 | 
			
		||||
                msg.sender == address(bench),
 | 
			
		||||
            "Only DAO core contracts may call burn"
 | 
			
		||||
        );
 | 
			
		||||
        rep.burn(account, value);
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +113,8 @@ contract DAO {
 | 
			
		|||
 | 
			
		||||
    function registerMember(address account) public {
 | 
			
		||||
        require(
 | 
			
		||||
            msg.sender == address(bench),
 | 
			
		||||
            msg.sender == address(lightweightBench) ||
 | 
			
		||||
                msg.sender == address(bench),
 | 
			
		||||
            "Only DAO core contracts may call registerMember"
 | 
			
		||||
        );
 | 
			
		||||
        if (!isMember[account]) {
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +183,7 @@ contract DAO {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function validationPools(
 | 
			
		||||
    function getValidationPool(
 | 
			
		||||
        uint poolIndex
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +201,7 @@ contract DAO {
 | 
			
		|||
        return bench.validationPools(poolIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function validationPoolCount() public view returns (uint) {
 | 
			
		||||
    function getValidationPoolCount() public view returns (uint) {
 | 
			
		||||
        return bench.validationPoolCount();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +238,6 @@ contract DAO {
 | 
			
		|||
            balanceOf(msg.sender) >= amount,
 | 
			
		||||
            "Insufficient REP balance to cover stake"
 | 
			
		||||
        );
 | 
			
		||||
        // TODO: Encumber tokens
 | 
			
		||||
        bench.stakeOnValidationPool(poolIndex, msg.sender, amount, inFavor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +259,104 @@ contract DAO {
 | 
			
		|||
        return bench.evaluateOutcome(poolIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getLWValidationPool(
 | 
			
		||||
        uint poolIndex
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (
 | 
			
		||||
            uint id,
 | 
			
		||||
            address sender,
 | 
			
		||||
            uint stakeCount,
 | 
			
		||||
            LWVPoolParams memory params,
 | 
			
		||||
            LWVPoolProps memory props,
 | 
			
		||||
            bool callbackOnValidate,
 | 
			
		||||
            bytes memory callbackData
 | 
			
		||||
        )
 | 
			
		||||
    {
 | 
			
		||||
        return lightweightBench.validationPools(poolIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getLWValidationPoolCount() public view returns (uint) {
 | 
			
		||||
        return lightweightBench.validationPoolCount();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function initiateLWValidationPool(
 | 
			
		||||
        string calldata postId,
 | 
			
		||||
        uint duration,
 | 
			
		||||
        uint[2] calldata quorum, // [Numerator, Denominator]
 | 
			
		||||
        uint[2] calldata winRatio, // [Numerator, Denominator]
 | 
			
		||||
        uint bindingPercent,
 | 
			
		||||
        bool redistributeLosingStakes,
 | 
			
		||||
        bool callbackOnValidate,
 | 
			
		||||
        bytes calldata callbackData
 | 
			
		||||
    ) external payable returns (uint) {
 | 
			
		||||
        return
 | 
			
		||||
            lightweightBench.initiateValidationPool{value: msg.value}(
 | 
			
		||||
                msg.sender,
 | 
			
		||||
                postId,
 | 
			
		||||
                duration,
 | 
			
		||||
                quorum,
 | 
			
		||||
                winRatio,
 | 
			
		||||
                bindingPercent,
 | 
			
		||||
                redistributeLosingStakes,
 | 
			
		||||
                callbackOnValidate,
 | 
			
		||||
                callbackData
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function proposeLWResult(
 | 
			
		||||
        uint poolIndex,
 | 
			
		||||
        string calldata resultHash,
 | 
			
		||||
        Transfer[] calldata transfers
 | 
			
		||||
    ) external {
 | 
			
		||||
        lightweightBench.proposeResult(poolIndex, resultHash, transfers);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function stakeOnLWValidationPool(
 | 
			
		||||
        uint poolIndex,
 | 
			
		||||
        string calldata resultHash,
 | 
			
		||||
        uint256 amount,
 | 
			
		||||
        bool inFavor
 | 
			
		||||
    ) public {
 | 
			
		||||
        require(
 | 
			
		||||
            balanceOf(msg.sender) >= amount,
 | 
			
		||||
            "Insufficient REP balance to cover stake"
 | 
			
		||||
        );
 | 
			
		||||
        lightweightBench.stakeOnValidationPool(
 | 
			
		||||
            poolIndex,
 | 
			
		||||
            resultHash,
 | 
			
		||||
            msg.sender,
 | 
			
		||||
            amount,
 | 
			
		||||
            inFavor
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Accept reputation stakes toward a validation pool
 | 
			
		||||
    function delegatedStakeOnLWValidationPool(
 | 
			
		||||
        uint poolIndex,
 | 
			
		||||
        string calldata resultHash,
 | 
			
		||||
        address owner,
 | 
			
		||||
        uint256 amount,
 | 
			
		||||
        bool inFavor
 | 
			
		||||
    ) public {
 | 
			
		||||
        if (allowance(owner, msg.sender) < amount) {
 | 
			
		||||
            amount = allowance(owner, msg.sender);
 | 
			
		||||
        }
 | 
			
		||||
        rep.spendAllowance(owner, msg.sender, amount);
 | 
			
		||||
        lightweightBench.stakeOnValidationPool(
 | 
			
		||||
            poolIndex,
 | 
			
		||||
            resultHash,
 | 
			
		||||
            owner,
 | 
			
		||||
            amount,
 | 
			
		||||
            inFavor
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function evaluateLWOutcome(uint poolIndex) public returns (bool) {
 | 
			
		||||
        return lightweightBench.evaluateOutcome(poolIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function onValidate(
 | 
			
		||||
        address target,
 | 
			
		||||
        bool votePasses,
 | 
			
		||||
| 
						 | 
				
			
			@ -241,7 +366,8 @@ contract DAO {
 | 
			
		|||
        bytes calldata callbackData
 | 
			
		||||
    ) public {
 | 
			
		||||
        require(
 | 
			
		||||
            msg.sender == address(bench),
 | 
			
		||||
            msg.sender == address(lightweightBench) ||
 | 
			
		||||
                msg.sender == address(bench),
 | 
			
		||||
            "Only DAO core contracts may call onValidate"
 | 
			
		||||
        );
 | 
			
		||||
        IOnValidate(target).onValidate(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,13 +20,13 @@ struct LWVPoolProps {
 | 
			
		|||
    bool outcome;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract LightweightBench {
 | 
			
		||||
    struct Transfer {
 | 
			
		||||
        address from;
 | 
			
		||||
        address to;
 | 
			
		||||
        uint amount;
 | 
			
		||||
    }
 | 
			
		||||
struct Transfer {
 | 
			
		||||
    address from;
 | 
			
		||||
    address to;
 | 
			
		||||
    uint amount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract LightweightBench {
 | 
			
		||||
    struct ProposedResult {
 | 
			
		||||
        Transfer[] transfers;
 | 
			
		||||
        uint stakedFor;
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +121,10 @@ contract LightweightBench {
 | 
			
		|||
        string calldata resultHash,
 | 
			
		||||
        Transfer[] calldata transfers
 | 
			
		||||
    ) external {
 | 
			
		||||
        require(
 | 
			
		||||
            transfers.length > 0,
 | 
			
		||||
            "The proposed result contains no transfers"
 | 
			
		||||
        );
 | 
			
		||||
        Pool storage pool = validationPools[poolIndex];
 | 
			
		||||
        require(
 | 
			
		||||
            block.timestamp <= pool.props.endTime,
 | 
			
		||||
| 
						 | 
				
			
			@ -129,14 +133,16 @@ contract LightweightBench {
 | 
			
		|||
        ProposedResult storage proposedResult = pool.proposedResults[
 | 
			
		||||
            resultHash
 | 
			
		||||
        ];
 | 
			
		||||
        pool.proposedResultHashes.push(resultHash);
 | 
			
		||||
        require(
 | 
			
		||||
            proposedResult.transfers.length == 0,
 | 
			
		||||
            "This result hash has already been proposed"
 | 
			
		||||
        );
 | 
			
		||||
        uint resultIndex = pool.proposedResultHashes.length;
 | 
			
		||||
        pool.proposedResultHashes.push(resultHash);
 | 
			
		||||
        for (uint i = 0; i < transfers.length; i++) {
 | 
			
		||||
            proposedResult.transfers.push(transfers[i]);
 | 
			
		||||
        }
 | 
			
		||||
        dao.emitLWResultProposed(poolIndex, resultIndex, resultHash);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Register a stake for/against a validation pool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ const fetchPost = async (postIndex) => {
 | 
			
		|||
const fetchValidationPool = async (poolIndex) => {
 | 
			
		||||
  const {
 | 
			
		||||
    id, postIndex, sender, stakeCount, fee, duration, endTime, resolved, outcome,
 | 
			
		||||
  } = await dao.validationPools(poolIndex);
 | 
			
		||||
  } = await dao.getValidationPool(poolIndex);
 | 
			
		||||
  const pool = {
 | 
			
		||||
    id, postIndex, sender, stakeCount, fee, duration, endTime, resolved, outcome,
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ const fetchValidationPool = async (poolIndex) => {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
const fetchValidationPools = async () => {
 | 
			
		||||
  const count = await dao.validationPoolCount();
 | 
			
		||||
  const count = await dao.getValidationPoolCount();
 | 
			
		||||
  console.log(`validation pool count: ${count}`);
 | 
			
		||||
  const promises = [];
 | 
			
		||||
  validationPools = [];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ describe('Forum', () => {
 | 
			
		|||
      await addPost(account1, 'content-id', []);
 | 
			
		||||
      await addPost(account2, 'second-content-id', [{ weightPPM: 500000, targetPostId: 'content-id' }]);
 | 
			
		||||
      await initiateValidationPool({ postId: 'second-content-id' });
 | 
			
		||||
      const pool = await dao.validationPools(0);
 | 
			
		||||
      const pool = await dao.getValidationPool(0);
 | 
			
		||||
      expect(pool.props.postId).to.equal('second-content-id');
 | 
			
		||||
      await dao.evaluateOutcome(0);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(50);
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ describe('Forum', () => {
 | 
			
		|||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      await addPost(account2, 'second-content-id', [{ weightPPM: -500000, targetPostId: 'content-id' }]);
 | 
			
		||||
      await initiateValidationPool({ postId: 'second-content-id' });
 | 
			
		||||
      const pool = await dao.validationPools(1);
 | 
			
		||||
      const pool = await dao.getValidationPool(1);
 | 
			
		||||
      expect(pool.props.postId).to.equal('second-content-id');
 | 
			
		||||
      await time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await dao.evaluateOutcome(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ describe('Forum', () => {
 | 
			
		|||
        { weightPPM: 1000000, targetPostId: 'second-content-id' },
 | 
			
		||||
      ]);
 | 
			
		||||
      await initiateValidationPool({ postId: 'third-content-id' });
 | 
			
		||||
      const pool = await dao.validationPools(1);
 | 
			
		||||
      const pool = await dao.getValidationPool(1);
 | 
			
		||||
      expect(pool.props.postId).to.equal('third-content-id');
 | 
			
		||||
      await time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await dao.evaluateOutcome(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +183,7 @@ describe('Forum', () => {
 | 
			
		|||
        { weightPPM: 100000, targetPostId: 'nonexistent-content-id' },
 | 
			
		||||
      ]);
 | 
			
		||||
      await initiateValidationPool({ postId: 'second-content-id' });
 | 
			
		||||
      const pool = await dao.validationPools(0);
 | 
			
		||||
      const pool = await dao.getValidationPool(0);
 | 
			
		||||
      expect(pool.props.postId).to.equal('second-content-id');
 | 
			
		||||
      await dao.evaluateOutcome(0);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(10);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,318 @@
 | 
			
		|||
const {
 | 
			
		||||
  time,
 | 
			
		||||
  loadFixture,
 | 
			
		||||
} = require('@nomicfoundation/hardhat-toolbox/network-helpers');
 | 
			
		||||
const { expect } = require('chai');
 | 
			
		||||
const { ethers } = require('hardhat');
 | 
			
		||||
const deployDAO = require('./util/deploy-dao');
 | 
			
		||||
 | 
			
		||||
describe('Lightweight Validation Pools', () => {
 | 
			
		||||
  async function deploy() {
 | 
			
		||||
    const [account1, account2] = await ethers.getSigners();
 | 
			
		||||
    const { dao, forum } = await deployDAO();
 | 
			
		||||
    return {
 | 
			
		||||
      dao, forum, account1, account2,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  let dao;
 | 
			
		||||
  let forum;
 | 
			
		||||
  let account1;
 | 
			
		||||
  let account2;
 | 
			
		||||
  const POOL_DURATION = 3600; // 1 hour
 | 
			
		||||
  const POOL_FEE = 100;
 | 
			
		||||
  const emptyCallbackData = ethers.AbiCoder.defaultAbiCoder().encode([], []);
 | 
			
		||||
 | 
			
		||||
  const initiateValidationPool = ({
 | 
			
		||||
    postId, duration,
 | 
			
		||||
    quorum, winRatio, bindingPercent,
 | 
			
		||||
    redistributeLosingStakes, callbackOnValidate,
 | 
			
		||||
    callbackData, fee,
 | 
			
		||||
  } = {}) => dao.initiateLWValidationPool(
 | 
			
		||||
    postId ?? 'content-id',
 | 
			
		||||
    duration ?? POOL_DURATION,
 | 
			
		||||
    quorum ?? [1, 3],
 | 
			
		||||
    winRatio ?? [1, 2],
 | 
			
		||||
    bindingPercent ?? 100,
 | 
			
		||||
    redistributeLosingStakes ?? true,
 | 
			
		||||
    callbackOnValidate ?? false,
 | 
			
		||||
    callbackData ?? emptyCallbackData,
 | 
			
		||||
    { value: fee ?? POOL_FEE },
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  beforeEach(async () => {
 | 
			
		||||
    ({
 | 
			
		||||
      dao, forum, account1, account2,
 | 
			
		||||
    } = await loadFixture(deploy));
 | 
			
		||||
    await forum.addPost([{ weightPPM: 1000000, authorAddress: account1 }], 'content-id', []);
 | 
			
		||||
    const init = () => initiateValidationPool({ fee: POOL_FEE });
 | 
			
		||||
    await expect(init()).to.emit(dao, 'LWValidationPoolInitiated').withArgs(0);
 | 
			
		||||
    expect(await dao.getLWValidationPoolCount()).to.equal(1);
 | 
			
		||||
    expect(await dao.memberCount()).to.equal(0);
 | 
			
		||||
    expect(await dao.balanceOf(account1)).to.equal(0);
 | 
			
		||||
    expect(await dao.totalSupply()).to.equal(POOL_FEE);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Initiate', () => {
 | 
			
		||||
    it('should be able to initiate a validation pool without a fee', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool({ fee: 0 });
 | 
			
		||||
      await expect(init()).to.emit(dao, 'LWValidationPoolInitiated');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to initiate a validation pool with a quorum below the minimum', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool({ quorum: [1, 11] });
 | 
			
		||||
      await expect(init()).to.be.revertedWith('Quorum is below minimum');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to initiate a validation pool with a quorum greater than 1', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool({ quorum: [11, 10] });
 | 
			
		||||
      await expect(init()).to.be.revertedWith('Quorum is greater than one');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to initiate a validation pool with duration below minimum', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool({ duration: 0 });
 | 
			
		||||
      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 init = () => initiateValidationPool({ duration: 40000000000000 });
 | 
			
		||||
      await expect(init()).to.be.revertedWith('Duration is too long');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to initiate a validation pool with bindingPercent above 100', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool({ bindingPercent: 101 });
 | 
			
		||||
      await expect(init()).to.be.revertedWith('Binding percent must be <= 100');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should be able to initiate a second validation pool', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool();
 | 
			
		||||
      await expect(init()).to.emit(dao, 'LWValidationPoolInitiated').withArgs(1);
 | 
			
		||||
      expect(await dao.getLWValidationPoolCount()).to.equal(2);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('Should be able to fetch pool instance', async () => {
 | 
			
		||||
      const pool = await dao.getLWValidationPool(0);
 | 
			
		||||
      expect(pool).to.exist;
 | 
			
		||||
      expect(pool.params.duration).to.equal(POOL_DURATION);
 | 
			
		||||
      expect(pool.props.postId).to.equal('content-id');
 | 
			
		||||
      expect(pool.props.resolved).to.be.false;
 | 
			
		||||
      expect(pool.sender).to.equal(account1);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Propose Result', () => {
 | 
			
		||||
    it('should not be able to propose an empty result', async () => {
 | 
			
		||||
      await expect(dao.proposeLWResult(0, 'some-hash', [])).to.be.revertedWith('The proposed result contains no transfers');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should be able to propose a result', async () => {
 | 
			
		||||
      await expect(dao.proposeLWResult(0, 'some-hash', [{ from: account1, to: account2, amount: 0 }])).to.emit(dao, 'LWResultProposed').withArgs(0, 0, 'some-hash');
 | 
			
		||||
      await expect(dao.proposeLWResult(0, 'some-other-hash', [{ from: account1, to: account2, amount: 0 }])).to.emit(dao, 'LWResultProposed').withArgs(0, 1, 'some-other-hash');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to propose the same result twice', async () => {
 | 
			
		||||
      await expect(dao.proposeLWResult(0, 'some-hash', [{ from: account1, to: account2, amount: 0 }])).to.emit(dao, 'LWResultProposed').withArgs(0, 0, 'some-hash');
 | 
			
		||||
      await expect(dao.proposeLWResult(0, 'some-hash', [{ from: account1, to: account2, amount: 0 }])).to.be.revertedWith('This result hash has already been proposed');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
      await initiateValidationPool();
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should be able to stake before validation pool has elapsed', async () => {
 | 
			
		||||
      await dao.stakeOnLWValidationPool(1, 10, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, true, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to stake after validation pool has elapsed', async () => {
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.stakeOnValidationPool(1, 10, true)).to.be.revertedWith('Pool end time has passed');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should be able to stake against a validation pool', async () => {
 | 
			
		||||
      await dao.stakeOnValidationPool(1, 10, false);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, false, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
      const pool = await dao.getValidationPool(1);
 | 
			
		||||
      expect(pool.props.outcome).to.be.false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to stake more REP than the sender owns', async () => {
 | 
			
		||||
      await expect(dao.stakeOnValidationPool(1, 200, true)).to.be.revertedWith('Insufficient REP balance to cover stake');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Delegated stake', () => {
 | 
			
		||||
    it('should stake the lesser of the allowed amount or the owner\'s remaining balance', async () => {
 | 
			
		||||
      // TODO: owner delegates stake and then loses rep
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Evaluate outcome', () => {
 | 
			
		||||
    it('should not be able to evaluate outcome before duration has elapsed if not all rep has been staked', async () => {
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(0));
 | 
			
		||||
      await initiateValidationPool({ fee: 100 });
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.be.revertedWith('Pool end time has not yet arrived');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to evaluate outcome before duration has elapsed unless all rep has been staked', async () => {
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(0));
 | 
			
		||||
      await initiateValidationPool({ fee: 100 });
 | 
			
		||||
      await dao.stakeOnValidationPool(1, 100, true);
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, true, true);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should be able to evaluate outcome after duration has elapsed', async () => {
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true, true);
 | 
			
		||||
      expect(await dao.memberCount()).to.equal(1);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      const pool = await dao.getValidationPool(0);
 | 
			
		||||
      expect(pool.props.resolved).to.be.true;
 | 
			
		||||
      expect(pool.props.outcome).to.be.true;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    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, 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 () => {
 | 
			
		||||
      const init = () => initiateValidationPool();
 | 
			
		||||
      await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
 | 
			
		||||
      expect(await dao.getValidationPoolCount()).to.equal(2);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, true, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not be able to evaluate outcome if quorum is not met', async () => {
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true, true);
 | 
			
		||||
 | 
			
		||||
      const init = () => initiateValidationPool({ quorum: [1, 1] });
 | 
			
		||||
      await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
 | 
			
		||||
      expect(await dao.getValidationPoolCount()).to.equal(2);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, false, false);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('Validation pool options', () => {
 | 
			
		||||
      beforeEach(async () => {
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(0);
 | 
			
		||||
        await forum.addPost([{ weightPPM: 1000000, authorAddress: account2 }], 'content-id-2', []);
 | 
			
		||||
        const init = () => initiateValidationPool({ postId: 'content-id-2' });
 | 
			
		||||
        await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(1);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('Binding validation pool should redistribute stakes', async () => {
 | 
			
		||||
        const init = () => initiateValidationPool();
 | 
			
		||||
        await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(2);
 | 
			
		||||
        await dao.connect(account1).stakeOnValidationPool(2, 10, true);
 | 
			
		||||
        await dao.connect(account2).stakeOnValidationPool(2, 10, false);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(2);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(210);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(90);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('Non binding validation pool should not redistribute stakes', async () => {
 | 
			
		||||
        const init = () => initiateValidationPool({ bindingPercent: 0 });
 | 
			
		||||
        await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(2);
 | 
			
		||||
        await dao.connect(account1).stakeOnValidationPool(2, 10, true);
 | 
			
		||||
        await dao.connect(account2).stakeOnValidationPool(2, 10, false);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(2);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('Partially binding validation pool should redistribute some stakes', async () => {
 | 
			
		||||
        const init = () => initiateValidationPool({ bindingPercent: 50 });
 | 
			
		||||
        await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(2);
 | 
			
		||||
        await dao.connect(account1).stakeOnValidationPool(2, 10, true);
 | 
			
		||||
        await dao.connect(account2).stakeOnValidationPool(2, 10, false);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(2);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(205);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(95);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
        expect(await dao.totalSupply()).to.equal(300);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('If redistributeLosingStakes is false, validation pool should burn binding portion of losing stakes', async () => {
 | 
			
		||||
        const init = () => initiateValidationPool({
 | 
			
		||||
          bindingPercent: 50,
 | 
			
		||||
          redistributeLosingStakes: false,
 | 
			
		||||
        });
 | 
			
		||||
        await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(2);
 | 
			
		||||
        await dao.connect(account1).stakeOnValidationPool(2, 10, true);
 | 
			
		||||
        await dao.connect(account2).stakeOnValidationPool(2, 10, false);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(2);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(95);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
        expect(await dao.totalSupply()).to.equal(295);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('If redistributeLosingStakes is false and bindingPercent is 0, accounts should recover initial balances', async () => {
 | 
			
		||||
        const init = () => initiateValidationPool({
 | 
			
		||||
          bindingPercent: 0,
 | 
			
		||||
          redistributeLosingStakes: false,
 | 
			
		||||
        });
 | 
			
		||||
        await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(2);
 | 
			
		||||
        await dao.connect(account1).stakeOnValidationPool(2, 10, true);
 | 
			
		||||
        await dao.connect(account2).stakeOnValidationPool(2, 10, false);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(100);
 | 
			
		||||
        time.increase(POOL_DURATION + 1);
 | 
			
		||||
        await dao.evaluateOutcome(2);
 | 
			
		||||
        expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
        expect(await dao.balanceOf(account2)).to.equal(100);
 | 
			
		||||
        expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
        expect(await dao.totalSupply()).to.equal(300);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ describe('Onboarding', () => {
 | 
			
		|||
      expect(post.authors).to.have.length(1);
 | 
			
		||||
      expect(post.authors[0].weightPPM).to.equal(1000000);
 | 
			
		||||
      expect(post.authors[0].authorAddress).to.equal(account1);
 | 
			
		||||
      const pool = await dao.validationPools(1);
 | 
			
		||||
      const pool = await dao.getValidationPool(1);
 | 
			
		||||
      expect(pool.props.postId).to.equal('evidence-content-id');
 | 
			
		||||
      expect(pool.props.fee).to.equal(PRICE * 0.9);
 | 
			
		||||
      expect(pool.sender).to.equal(onboarding.target);
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ describe('Onboarding', () => {
 | 
			
		|||
      expect(post.authors).to.have.length(1);
 | 
			
		||||
      expect(post.authors[0].weightPPM).to.equal(1000000);
 | 
			
		||||
      expect(post.authors[0].authorAddress).to.equal(account2);
 | 
			
		||||
      const pool = await dao.validationPools(2);
 | 
			
		||||
      const pool = await dao.getValidationPool(2);
 | 
			
		||||
      expect(pool.props.postId).to.equal('req-content-id');
 | 
			
		||||
      expect(pool.props.fee).to.equal(PRICE * 0.1);
 | 
			
		||||
      expect(pool.sender).to.equal(onboarding.target);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -224,7 +224,7 @@ describe('Proposal', () => {
 | 
			
		|||
      });
 | 
			
		||||
 | 
			
		||||
      afterEach(async () => {
 | 
			
		||||
        const pool = await dao.validationPools(3);
 | 
			
		||||
        const pool = await dao.getValidationPool(3);
 | 
			
		||||
        expect(pool.props.resolved).to.be.true;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +310,7 @@ describe('Proposal', () => {
 | 
			
		|||
      });
 | 
			
		||||
 | 
			
		||||
      afterEach(async () => {
 | 
			
		||||
        const pool = await dao.validationPools(4);
 | 
			
		||||
        const pool = await dao.getValidationPool(4);
 | 
			
		||||
        expect(pool.props.resolved).to.be.true;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ describe('Validation Pools', () => {
 | 
			
		|||
    await forum.addPost([{ weightPPM: 1000000, authorAddress: account1 }], 'content-id', []);
 | 
			
		||||
    const init = () => initiateValidationPool({ fee: POOL_FEE });
 | 
			
		||||
    await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(0);
 | 
			
		||||
    expect(await dao.validationPoolCount()).to.equal(1);
 | 
			
		||||
    expect(await dao.getValidationPoolCount()).to.equal(1);
 | 
			
		||||
    expect(await dao.memberCount()).to.equal(0);
 | 
			
		||||
    expect(await dao.balanceOf(account1)).to.equal(0);
 | 
			
		||||
    expect(await dao.totalSupply()).to.equal(POOL_FEE);
 | 
			
		||||
| 
						 | 
				
			
			@ -86,11 +86,11 @@ describe('Validation Pools', () => {
 | 
			
		|||
    it('should be able to initiate a second validation pool', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool();
 | 
			
		||||
      await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
 | 
			
		||||
      expect(await dao.validationPoolCount()).to.equal(2);
 | 
			
		||||
      expect(await dao.getValidationPoolCount()).to.equal(2);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('Should be able to fetch pool instance', async () => {
 | 
			
		||||
      const pool = await dao.validationPools(0);
 | 
			
		||||
      const pool = await dao.getValidationPool(0);
 | 
			
		||||
      expect(pool).to.exist;
 | 
			
		||||
      expect(pool.params.duration).to.equal(POOL_DURATION);
 | 
			
		||||
      expect(pool.props.postId).to.equal('content-id');
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ describe('Validation Pools', () => {
 | 
			
		|||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, false, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(200);
 | 
			
		||||
      expect(await dao.balanceOf(dao.target)).to.equal(0);
 | 
			
		||||
      const pool = await dao.validationPools(1);
 | 
			
		||||
      const pool = await dao.getValidationPool(1);
 | 
			
		||||
      expect(pool.props.outcome).to.be.false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +170,7 @@ describe('Validation Pools', () => {
 | 
			
		|||
      await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true, true);
 | 
			
		||||
      expect(await dao.memberCount()).to.equal(1);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
      const pool = await dao.validationPools(0);
 | 
			
		||||
      const pool = await dao.getValidationPool(0);
 | 
			
		||||
      expect(pool.props.resolved).to.be.true;
 | 
			
		||||
      expect(pool.props.outcome).to.be.true;
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			@ -184,7 +184,7 @@ describe('Validation Pools', () => {
 | 
			
		|||
    it('should be able to evaluate outcome of second validation pool', async () => {
 | 
			
		||||
      const init = () => initiateValidationPool();
 | 
			
		||||
      await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
 | 
			
		||||
      expect(await dao.validationPoolCount()).to.equal(2);
 | 
			
		||||
      expect(await dao.getValidationPoolCount()).to.equal(2);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(0)).to.emit(dao, 'ValidationPoolResolved').withArgs(0, true, true);
 | 
			
		||||
      expect(await dao.balanceOf(account1)).to.equal(100);
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +198,7 @@ describe('Validation Pools', () => {
 | 
			
		|||
 | 
			
		||||
      const init = () => initiateValidationPool({ quorum: [1, 1] });
 | 
			
		||||
      await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
 | 
			
		||||
      expect(await dao.validationPoolCount()).to.equal(2);
 | 
			
		||||
      expect(await dao.getValidationPoolCount()).to.equal(2);
 | 
			
		||||
      time.increase(POOL_DURATION + 1);
 | 
			
		||||
      await expect(dao.evaluateOutcome(1)).to.emit(dao, 'ValidationPoolResolved').withArgs(1, false, false);
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -229,7 +229,7 @@ describe('Work1', () => {
 | 
			
		|||
      expect(post.authors).to.have.length(1);
 | 
			
		||||
      expect(post.authors[0].weightPPM).to.equal(1000000);
 | 
			
		||||
      expect(post.authors[0].authorAddress).to.equal(account1);
 | 
			
		||||
      const pool = await dao.validationPools(1);
 | 
			
		||||
      const pool = await dao.getValidationPool(1);
 | 
			
		||||
      expect(pool.props.fee).to.equal(WORK1_PRICE);
 | 
			
		||||
      expect(pool.sender).to.equal(work1.target);
 | 
			
		||||
      expect(pool.props.postId).to.equal('evidence-content-id');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,14 +3,17 @@ const { ethers } = require('hardhat');
 | 
			
		|||
const deployDAO = async () => {
 | 
			
		||||
  const Reputation = await ethers.getContractFactory('Reputation');
 | 
			
		||||
  const Bench = await ethers.getContractFactory('Bench');
 | 
			
		||||
  const LightweightBench = await ethers.getContractFactory('LightweightBench');
 | 
			
		||||
  const DAO = await ethers.getContractFactory('DAO');
 | 
			
		||||
  const GlobalForum = await ethers.getContractFactory('GlobalForum');
 | 
			
		||||
  const forum = await GlobalForum.deploy();
 | 
			
		||||
  const reputation = await Reputation.deploy();
 | 
			
		||||
  const bench = await Bench.deploy();
 | 
			
		||||
  const lightweightBench = await LightweightBench.deploy();
 | 
			
		||||
  const dao = await DAO.deploy(
 | 
			
		||||
    reputation.target,
 | 
			
		||||
    bench.target,
 | 
			
		||||
    lightweightBench.target,
 | 
			
		||||
    forum.target,
 | 
			
		||||
  );
 | 
			
		||||
  return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue