add post
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 29s
Details
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 29s
Details
This commit is contained in:
parent
d8e4d4fd6a
commit
83f8474905
|
@ -6,6 +6,11 @@ import "./IAcceptAvailability.sol";
|
|||
|
||||
import "hardhat/console.sol";
|
||||
|
||||
struct Post {
|
||||
address sender;
|
||||
address author;
|
||||
}
|
||||
|
||||
struct Stake {
|
||||
bool inFavor;
|
||||
uint256 amount;
|
||||
|
@ -13,9 +18,9 @@ struct Stake {
|
|||
}
|
||||
|
||||
struct ValidationPool {
|
||||
Post post;
|
||||
mapping(uint => Stake) stakes;
|
||||
uint stakeCount;
|
||||
address author;
|
||||
uint256 fee;
|
||||
uint256 initialStakedFor;
|
||||
uint256 initialStakedAgainst;
|
||||
|
@ -39,6 +44,8 @@ contract DAO is ERC20("Reputation", "REP") {
|
|||
mapping(address => bool) public isMember;
|
||||
mapping(uint => ValidationPool) public validationPools;
|
||||
uint public validationPoolCount;
|
||||
mapping(uint => Post) public posts;
|
||||
uint public postCount;
|
||||
|
||||
// ufixed8x1 constant mintingRatio = 1;
|
||||
// ufixed8x1 constant quorum = 0;
|
||||
|
@ -50,18 +57,24 @@ contract DAO is ERC20("Reputation", "REP") {
|
|||
event ValidationPoolInitiated(uint poolIndex);
|
||||
event ValidationPoolResolved(uint poolIndex, bool votePasses);
|
||||
|
||||
function addPost(address author) public returns (uint postIndex) {
|
||||
postIndex = postCount++;
|
||||
Post storage post = posts[postIndex];
|
||||
post.author = author;
|
||||
post.sender = msg.sender;
|
||||
}
|
||||
|
||||
/// Accept fee to initiate a validation pool
|
||||
/// TODO: Rather than accept author as a parameter, accept a reference to a forum post
|
||||
/// TODO: Handle multiple authors
|
||||
/// TODO: Constrain duration to allowable range
|
||||
function initiateValidationPool(
|
||||
address author,
|
||||
uint postIndex,
|
||||
uint duration
|
||||
) public payable returns (uint poolIndex) {
|
||||
require(msg.value > 0, "Fee is required to initiate validation pool");
|
||||
poolIndex = validationPoolCount++;
|
||||
ValidationPool storage pool = validationPools[poolIndex];
|
||||
pool.author = author;
|
||||
pool.post = posts[postIndex];
|
||||
pool.fee = msg.value;
|
||||
pool.duration = duration;
|
||||
pool.endTime = block.timestamp + duration;
|
||||
|
@ -71,10 +84,10 @@ contract DAO is ERC20("Reputation", "REP") {
|
|||
// Implementing this with adjustable parameters will require more advanced fixed point math.
|
||||
// TODO: Make minting ratio an adjustable parameter
|
||||
// TODO: Make stakeForAuthor an adjustable parameter
|
||||
_mint(author, msg.value);
|
||||
_mint(pool.post.author, msg.value);
|
||||
// TODO: We need a way to exclude this pending reputation from the total supply when computing fee distribution
|
||||
_stake(pool, author, msg.value / 2, true);
|
||||
_stake(pool, author, msg.value / 2, false);
|
||||
_stake(pool, pool.post.author, msg.value / 2, true);
|
||||
_stake(pool, pool.post.author, msg.value / 2, false);
|
||||
emit ValidationPoolInitiated(poolIndex);
|
||||
}
|
||||
|
||||
|
@ -124,9 +137,9 @@ contract DAO is ERC20("Reputation", "REP") {
|
|||
// This is especially important so that the DAO's first pool can pass,
|
||||
// when no reputation has yet been minted.
|
||||
votePasses = stakedFor >= stakedAgainst;
|
||||
if (votePasses && !isMember[pool.author]) {
|
||||
members[memberCount++] = pool.author;
|
||||
isMember[pool.author] = true;
|
||||
if (votePasses && !isMember[pool.post.author]) {
|
||||
members[memberCount++] = pool.post.author;
|
||||
isMember[pool.post.author] = true;
|
||||
}
|
||||
pool.resolved = true;
|
||||
emit ValidationPoolResolved(poolIndex, votePasses);
|
||||
|
@ -146,7 +159,7 @@ contract DAO is ERC20("Reputation", "REP") {
|
|||
// Due to rounding, there may be some reward left over. Include this as a reward to the author.
|
||||
uint256 remainder = amountFromLosers - totalRewards;
|
||||
if (remainder > 0) {
|
||||
_transfer(address(this), pool.author, remainder);
|
||||
_transfer(address(this), pool.post.author, remainder);
|
||||
}
|
||||
// Distribute fee proportionatly among all reputation holders
|
||||
for (uint i = 0; i < memberCount; i++) {
|
||||
|
|
|
@ -149,9 +149,11 @@ contract Work1 is IAcceptAvailability {
|
|||
AvailabilityStake storage stake = stakes[request.stakeIndex];
|
||||
request.status = WorkStatus.ApprovalSubmitted;
|
||||
request.approval = approval;
|
||||
// Make work evidence post
|
||||
uint postIndex = dao.addPost(stake.worker);
|
||||
// Initiate validation pool
|
||||
request.poolIndex = dao.initiateValidationPool{value: request.fee}(
|
||||
stake.worker,
|
||||
postIndex,
|
||||
POOL_DURATION
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,16 +6,10 @@ const { expect } = require('chai');
|
|||
const { ethers } = require('hardhat');
|
||||
|
||||
describe('DAO', () => {
|
||||
// We define a fixture to reuse the same setup in every test.
|
||||
// We use loadFixture to run this setup once, snapshot that state,
|
||||
// and reset Hardhat Network to that snapshot in every test.
|
||||
async function deploy() {
|
||||
// Contracts are deployed using the first signer/account by default
|
||||
const [account1, account2] = await ethers.getSigners();
|
||||
|
||||
const DAO = await ethers.getContractFactory('DAO');
|
||||
const dao = await DAO.deploy();
|
||||
|
||||
return { dao, account1, account2 };
|
||||
}
|
||||
|
||||
|
@ -25,6 +19,24 @@ describe('DAO', () => {
|
|||
expect(await dao.totalSupply()).to.equal(0);
|
||||
});
|
||||
|
||||
describe('Post', () => {
|
||||
it('should be able to add a post', async () => {
|
||||
const { dao, account1 } = await loadFixture(deploy);
|
||||
await dao.addPost(account1);
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Validation Pool', () => {
|
||||
let dao;
|
||||
let account1;
|
||||
|
@ -35,7 +47,8 @@ describe('DAO', () => {
|
|||
const setup = await loadFixture(deploy);
|
||||
dao = setup.dao;
|
||||
account1 = setup.account1;
|
||||
const init = () => dao.initiateValidationPool(account1, POOL_DURATION, { value: POOL_FEE });
|
||||
await dao.addPost(account1);
|
||||
const init = () => dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
||||
await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(0);
|
||||
expect(await dao.validationPoolCount()).to.equal(1);
|
||||
expect(await dao.memberCount()).to.equal(0);
|
||||
|
@ -46,12 +59,12 @@ describe('DAO', () => {
|
|||
describe('Initiate', () => {
|
||||
it('should not be able to initiate a validation pool without a fee', async () => {
|
||||
const setup = await loadFixture(deploy);
|
||||
const init = () => setup.dao.initiateValidationPool(setup.account1, POOL_DURATION);
|
||||
const init = () => setup.dao.initiateValidationPool(0, POOL_DURATION);
|
||||
await expect(init()).to.be.revertedWith('Fee is required to initiate validation pool');
|
||||
});
|
||||
|
||||
it('should be able to initiate a second validation pool', async () => {
|
||||
const init = () => dao.initiateValidationPool(account1, POOL_DURATION, { value: POOL_FEE });
|
||||
const init = () => dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
||||
await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
|
||||
expect(await dao.validationPoolCount()).to.equal(2);
|
||||
});
|
||||
|
@ -82,7 +95,7 @@ describe('DAO', () => {
|
|||
});
|
||||
|
||||
it('should be able to evaluate outcome of second validation pool', async () => {
|
||||
const init = () => dao.initiateValidationPool(account1, POOL_DURATION, { value: POOL_FEE });
|
||||
const init = () => dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
||||
await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
|
||||
expect(await dao.validationPoolCount()).to.equal(2);
|
||||
time.increase(POOL_DURATION + 1);
|
||||
|
@ -99,7 +112,7 @@ describe('DAO', () => {
|
|||
await dao.evaluateOutcome(0);
|
||||
expect(await dao.balanceOf(account1)).to.equal(100);
|
||||
expect(await dao.balanceOf(dao.target)).to.equal(0);
|
||||
await dao.initiateValidationPool(account1, POOL_DURATION, { value: POOL_FEE });
|
||||
await dao.initiateValidationPool(0, POOL_DURATION, { value: POOL_FEE });
|
||||
expect(await dao.balanceOf(dao.target)).to.equal(100);
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ describe('Work1', () => {
|
|||
const Work1 = await ethers.getContractFactory('Work1');
|
||||
const work1 = await Work1.deploy(dao.target, WORK1_PRICE);
|
||||
|
||||
await dao.initiateValidationPool(account1, 0, { value: 100 });
|
||||
await dao.addPost(account1);
|
||||
await dao.initiateValidationPool(0, 0, { value: 100 });
|
||||
await dao.evaluateOutcome(0);
|
||||
|
||||
return {
|
||||
|
@ -177,6 +178,12 @@ describe('Work1', () => {
|
|||
await expect(work1.submitWorkApproval(0, true)).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
|
||||
});
|
||||
|
||||
it('should be able to submit work disapproval', async () => {
|
||||
await work1.connect(account2).requestWork({ value: WORK1_PRICE });
|
||||
await work1.submitWorkEvidence(0);
|
||||
await expect(work1.submitWorkApproval(0, false)).to.emit(dao, 'ValidationPoolInitiated').withArgs(1);
|
||||
});
|
||||
|
||||
it('should not be able to submit work approval/disapproval twice', async () => {
|
||||
await work1.connect(account2).requestWork({ value: WORK1_PRICE });
|
||||
await work1.submitWorkEvidence(0);
|
||||
|
|
Loading…
Reference in New Issue