stake availability
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 34s Details

This commit is contained in:
Ladd Hoffman 2024-03-10 22:29:51 -05:00
parent c4fbce9f76
commit f59bfc3c9c
6 changed files with 91 additions and 28 deletions

View File

@ -2,6 +2,7 @@
pragma solidity ^0.8.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./IAcceptAvailability.sol";
struct Stake {
bool inFavor;
@ -69,6 +70,7 @@ contract DAO is ERC20("Reputation", "REP") {
// TODO: Make minting ratio an adjustable parameter
// TODO: Make stakeForAuthor an adjustable parameter
_mint(address(this), 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);
emit ValidationPoolInitiated(poolIndex);
@ -144,4 +146,19 @@ contract DAO is ERC20("Reputation", "REP") {
payable(member).transfer(share);
}
}
/// Transfer REP to a contract, and call that contract's receiveTransfer method
function stakeAvailability(
address to,
uint256 value,
uint duration
) external returns (bool transferred) {
transferred = super.transfer(to, value);
if (transferred)
IAcceptAvailability(to).acceptAvailability(
msg.sender,
value,
duration
);
}
}

View File

@ -0,0 +1,10 @@
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.24;
interface IAcceptAvailability {
function acceptAvailability(
address from,
uint256 value,
uint duration
) external;
}

View File

@ -1,15 +0,0 @@
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.24;
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
abstract contract ReputationHolder is IERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
}

View File

@ -2,11 +2,12 @@
pragma solidity ^0.8.24;
import "./DAO.sol";
import "./ReputationHolder.sol";
import "./IAcceptAvailability.sol";
struct AvailabilityStake {
address worker;
uint256 amount;
uint duration;
bool assigned;
}
@ -26,11 +27,11 @@ struct WorkRequest {
uint poolIndex;
}
contract Work1 is ReputationHolder {
contract Work1 is IAcceptAvailability {
DAO immutable dao;
uint public immutable price;
mapping(uint => AvailabilityStake) stakes;
uint stakeCount;
mapping(uint => AvailabilityStake) public stakes;
uint public stakeCount;
mapping(uint => WorkRequest) public requests;
uint public requestCount;
@ -45,13 +46,15 @@ contract Work1 is ReputationHolder {
}
/// Accept availability stakes as reputation token transfer
function stakeAvailability(uint256 amount) public {
require(dao.balanceOf(msg.sender) >= amount);
function acceptAvailability(
address sender,
uint256 amount,
uint duration
) external {
AvailabilityStake storage stake = stakes[stakeCount++];
stake.worker = msg.sender;
stake.worker = sender;
stake.amount = amount;
// TODO: Token locking
// TODO: Duration
stake.duration = duration;
}
/// Select a worker randomly from among the available workers, weighted by amount staked

View File

@ -9,7 +9,7 @@ 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 deployDAO() {
async function deploy() {
// Contracts are deployed using the first signer/account by default
const [account1, account2] = await ethers.getSigners();
@ -20,7 +20,7 @@ describe('DAO', () => {
}
it('Should deploy', async () => {
const { dao } = await loadFixture(deployDAO);
const { dao } = await loadFixture(deploy);
expect(dao).to.exist;
expect(await dao.totalValue()).to.equal(0);
});
@ -32,7 +32,7 @@ describe('DAO', () => {
const fee = 100;
beforeEach(async () => {
const setup = await loadFixture(deployDAO);
const setup = await loadFixture(deploy);
dao = setup.dao;
account1 = setup.account1;
const init = () => dao.initiateValidationPool(account1, POOL_DURATION, { value: fee });
@ -40,10 +40,11 @@ describe('DAO', () => {
expect(await dao.validationPoolCount()).to.equal(1);
expect(await dao.memberCount()).to.equal(0);
expect(await dao.balanceOf(account1)).to.equal(0);
expect(await dao.totalSupply()).to.equal(fee);
});
it('should not be able to initiate a validation pool without a fee', async () => {
const setup = await loadFixture(deployDAO);
const setup = await loadFixture(deploy);
const init = () => setup.dao.initiateValidationPool(setup.account1, POOL_DURATION);
await expect(init()).to.be.revertedWith('Fee is required to initiate validation pool');
});

47
ethereum/test/Work1.js Normal file
View File

@ -0,0 +1,47 @@
const {
loadFixture,
} = require('@nomicfoundation/hardhat-toolbox/network-helpers');
const { expect } = require('chai');
const { ethers } = require('hardhat');
describe('Work1', () => {
const WORK1_PRICE = 100;
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();
const Work1 = await ethers.getContractFactory('Work1');
const work1 = await Work1.deploy(dao.target, WORK1_PRICE);
await dao.initiateValidationPool(account1, 0, { value: 100 });
await dao.evaluateOutcome(0);
return {
dao, work1, account1, account2,
};
}
it('Should deploy', async () => {
const { dao, work1, account1 } = await loadFixture(deploy);
expect(dao).to.exist;
expect(work1).to.exist;
expect(await dao.memberCount()).to.equal(1);
expect(await dao.balanceOf(account1)).to.equal(100);
expect(await dao.totalSupply()).to.equal(100);
expect(await work1.stakeCount()).to.equal(0);
});
it('Should be able to receive availability stake', async () => {
const { dao, work1, account1 } = await loadFixture(deploy);
await dao.stakeAvailability(work1.target, 50, 60);
expect(await dao.balanceOf(account1)).to.equal(50);
expect(await dao.balanceOf(work1.target)).to.equal(50);
expect(await work1.stakeCount()).to.equal(1);
const stake = await work1.stakes(0);
expect(stake.worker).to.equal(account1);
expect(stake.amount).to.equal(50);
expect(stake.duration).to.equal(60);
});
});