diff --git a/ethereum/contracts/DAO.sol b/ethereum/contracts/DAO.sol index 1b19f71..991ed44 100644 --- a/ethereum/contracts/DAO.sol +++ b/ethereum/contracts/DAO.sol @@ -4,22 +4,41 @@ pragma solidity ^0.8.24; import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "./ReputationHolder.sol"; +struct Stake { + bool inFavor; + uint256 amount; + address worker; +} + +enum ValidationPoolStatus { + Open, + Closed +} + +struct ValidationPool { + mapping(uint => Stake) stakes; + uint stakeCount; + ValidationPoolStatus status; +} + /// This contract must manage validation pools and reputation, /// because otherwise there's no way to enforce appropriate permissions on /// transfer of value between reputation NFTs. contract DAO is ERC721("Reputation", "REP"), ReputationHolder { - mapping(uint256 tokenId => uint256) _tokenValues; - uint256 _nextTokenId; + mapping(uint256 tokenId => uint256) tokenValues; + uint256 nextTokenId; + mapping(uint => ValidationPool) validationPools; + uint validationPoolCount; /// Inspect the value of a given reputation NFT function valueOf(uint256 tokenId) public view returns (uint256 value) { - value = _tokenValues[tokenId]; + value = tokenValues[tokenId]; } /// Internal function to mint a new reputation NFT function mint() internal returns (uint256 tokenId) { // Generate a new (sequential) ID for the token - tokenId = _nextTokenId++; + tokenId = nextTokenId++; // Mint the token, initially to be owned by the current contract. _mint(address(this), tokenId); } @@ -32,7 +51,20 @@ contract DAO is ERC721("Reputation", "REP"), ReputationHolder { ) internal { require(amount >= 0); require(valueOf(fromTokenId) >= amount); - _tokenValues[fromTokenId] -= amount; - _tokenValues[toTokenId] += amount; + tokenValues[fromTokenId] -= amount; + tokenValues[toTokenId] += amount; + } + + /// Accept fee to initiate a validation pool + function initiateValidationPool() public {} + + /// Accept reputation stakes toward a validation pool + function onERC721Received( + address, + address from, + uint256 tokenId, + bytes calldata + ) public override returns (bytes4) { + return super.onERC721Received.selector; } } diff --git a/ethereum/contracts/ReputationHolder.sol b/ethereum/contracts/ReputationHolder.sol index 80c5327..6bfe6b7 100644 --- a/ethereum/contracts/ReputationHolder.sol +++ b/ethereum/contracts/ReputationHolder.sol @@ -1,6 +1,15 @@ // SPDX-License-Identifier: Unlicense pragma solidity ^0.8.24; -import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; -abstract contract ReputationHolder is ERC721Holder {} +abstract contract ReputationHolder is IERC721Receiver { + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) public virtual returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; + } +} diff --git a/ethereum/contracts/Work1.sol b/ethereum/contracts/Work1.sol index 4b0999c..9621271 100644 --- a/ethereum/contracts/Work1.sol +++ b/ethereum/contracts/Work1.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: Unlicense pragma solidity ^0.8.24; -import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "./DAO.sol"; import "./ReputationHolder.sol"; @@ -27,7 +26,7 @@ struct WorkRequest { bool approval; } -contract Work1 is IERC721Receiver { +contract Work1 is ReputationHolder { DAO dao; uint public immutable price; mapping(uint => AvailabilityStake) stakes; @@ -48,12 +47,12 @@ contract Work1 is IERC721Receiver { address from, uint256 tokenId, bytes calldata - ) external override returns (bytes4) { + ) public override returns (bytes4) { AvailabilityStake storage stake = stakes[stakeCount++]; stake.worker = from; stake.tokenId = tokenId; stake.amount = dao.valueOf(tokenId); - return IERC721Receiver.onERC721Received.selector; + return super.onERC721Received.selector; } /// Select a worker randomly from among the available workers, weighted by amount staked