From 77cd551602c28a4beabc0589b710bbc6d3b7d17c Mon Sep 17 00:00:00 2001 From: Ladd Hoffman Date: Wed, 10 Apr 2024 14:17:50 -0500 Subject: [PATCH] Hold minted REP until outcome is evaluated --- ethereum/contracts/core/ValidationPools.sol | 11 +++++- ethereum/test/DAO.js | 42 ++++++++++----------- ethereum/test/Work1.js | 2 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/ethereum/contracts/core/ValidationPools.sol b/ethereum/contracts/core/ValidationPools.sol index 7a8ba4b..6c51038 100644 --- a/ethereum/contracts/core/ValidationPools.sol +++ b/ethereum/contracts/core/ValidationPools.sol @@ -26,6 +26,7 @@ struct ValidationPool { uint id; uint postIndex; address sender; + uint minted; mapping(uint => ValidationPoolStake) stakes; uint stakeCount; ValidationPoolParams params; @@ -140,7 +141,8 @@ contract ValidationPools is Reputation, Forum { // We use our privilege as the DAO contract to mint reputation in proportion with the fee. // Here we assume a minting ratio of 1 // TODO: Make minting ratio an adjustable parameter - _mint(post.author, msg.value); + _mint(address(this), msg.value); + pool.minted = msg.value; // Here we assume a stakeForAuthor ratio of 0.5 // TODO: Make stakeForAuthor an adjustable parameter _stakeOnValidationPool(pool, post.author, msg.value / 2, true, true); @@ -193,6 +195,13 @@ contract ValidationPools is Reputation, Forum { return false; } + + // We are holding the REP minted on behalf of the author. + // We already registered their stakes. Now transfer the REP to the author, + // so that the stakes can be fulfilled. + _update(address(this), post.author, pool.minted); + // TODO: Transfer REP to the forum instead of to the author directly + // A tie is resolved in favor of the validation pool. // This is especially important so that the DAO's first pool can pass, // when no reputation has yet been minted. diff --git a/ethereum/test/DAO.js b/ethereum/test/DAO.js index e7d0477..20c19b0 100644 --- a/ethereum/test/DAO.js +++ b/ethereum/test/DAO.js @@ -73,7 +73,7 @@ describe('DAO', () => { await expect(init()).to.emit(dao, 'ValidationPoolInitiated').withArgs(0); expect(await dao.validationPoolCount()).to.equal(1); expect(await dao.memberCount()).to.equal(0); - expect(await dao.balanceOf(account1)).to.equal(100); + expect(await dao.balanceOf(account1)).to.equal(0); expect(await dao.totalSupply()).to.equal(POOL_FEE); }); @@ -131,18 +131,18 @@ describe('DAO', () => { 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(200); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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.stakeOnValidationPool(1, 10, true); - expect(await dao.balanceOf(account1)).to.equal(200); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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(dao.target)).to.equal(0); 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 () => { @@ -152,12 +152,12 @@ describe('DAO', () => { it('should be able to stake against a validation pool', async () => { await dao.stakeOnValidationPool(1, 10, false); - expect(await dao.balanceOf(account1)).to.equal(200); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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(dao.target)).to.equal(0); expect(await dao.balanceOf(account1)).to.equal(200); + expect(await dao.balanceOf(dao.target)).to.equal(0); const pool = await dao.validationPools(1); expect(pool.outcome).to.be.false; }); @@ -180,7 +180,7 @@ describe('DAO', () => { }); it('should be able to evaluate outcome after duration has elapsed', async () => { - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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); @@ -212,7 +212,7 @@ describe('DAO', () => { expect(await dao.validationPoolCount()).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(200); + 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); }); @@ -244,9 +244,9 @@ describe('DAO', () => { 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(200); + expect(await dao.balanceOf(account1)).to.equal(100); expect(await dao.balanceOf(account2)).to.equal(100); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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); @@ -259,9 +259,9 @@ describe('DAO', () => { 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(200); + expect(await dao.balanceOf(account1)).to.equal(100); expect(await dao.balanceOf(account2)).to.equal(100); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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); @@ -274,9 +274,9 @@ describe('DAO', () => { 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(200); + expect(await dao.balanceOf(account1)).to.equal(100); expect(await dao.balanceOf(account2)).to.equal(100); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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); @@ -293,9 +293,9 @@ describe('DAO', () => { 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(200); + expect(await dao.balanceOf(account1)).to.equal(100); expect(await dao.balanceOf(account2)).to.equal(100); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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); @@ -312,9 +312,9 @@ describe('DAO', () => { 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(200); + expect(await dao.balanceOf(account1)).to.equal(100); expect(await dao.balanceOf(account2)).to.equal(100); - expect(await dao.balanceOf(dao.target)).to.equal(0); + 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); diff --git a/ethereum/test/Work1.js b/ethereum/test/Work1.js index 7dd6f12..76c6de9 100644 --- a/ethereum/test/Work1.js +++ b/ethereum/test/Work1.js @@ -210,7 +210,7 @@ describe('Work1', () => { .to.emit(dao, 'ValidationPoolInitiated').withArgs(1) .to.emit(work1, 'WorkApprovalSubmitted').withArgs(0, true); expect(await dao.balanceOf(work1.target)).to.equal(0); - expect(await dao.balanceOf(account1)).to.equal(200); + expect(await dao.balanceOf(account1)).to.equal(100); const post = await dao.posts(1); expect(post.author).to.equal(account1); expect(post.sender).to.equal(work1.target);