Skip to content

Commit

Permalink
Initial version created
Browse files Browse the repository at this point in the history
  • Loading branch information
mobycrypt committed Aug 22, 2023
1 parent 9c58bcf commit 833d012
Show file tree
Hide file tree
Showing 37 changed files with 3,269 additions and 1,757 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat run scripts/deploy.ts
npx hardhat run scripts/deploy2.ts
```
70 changes: 70 additions & 0 deletions contracts/DAO.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
pragma solidity ^0.8.18;

import "./IProposal.sol";
import "./Proposal.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "hardhat/console.sol";
import "./ERC20DAOPool.sol";

abstract contract DAO {

mapping(bytes => IProposal) public proposals;
uint256 public challengePeriodSeconds = 1 minutes;
uint256 public nativeCollateral = 1 ether;
uint256 public tokenCollateral;
event ProposalCreated(bytes proposalId, address proposalAddress);

function validateTokenCollateral(address userAddress, uint256 requiredCollateral) public virtual returns (uint256);
function voteWithDaoToken(address proposalAddress, bool vote) public virtual;

// _tokenCollateral - should already include decimals
// _challengePeriod - in seconds
// _nativeCollateral - in wei
constructor(uint256 _tokenCollateral, uint256 _challengePeriod, uint256 _nativeCollateral) {
tokenCollateral = _tokenCollateral;
challengePeriodSeconds = _challengePeriod;
nativeCollateral = _nativeCollateral;
}

function setChallengePeriod(uint256 _challengePeriod) public {
challengePeriodSeconds = _challengePeriod;
}

function setChallengeCollateral(uint256 _challengeCollateral) public {
nativeCollateral = _challengeCollateral;
}

function createProposal(
bytes memory _proposalId,
bytes32 _proposalMerkleRoot,
address[] calldata _targets,
uint256[] calldata _values,
bytes[] calldata _payloads) payable public {
IProposal existingPool = proposals[_proposalId];
require(address(existingPool) == address(0), "Proposal already exists");
IProposal prop = new Proposal{value: msg.value}(_proposalMerkleRoot, _proposalId, payable(msg.sender), nativeCollateral, tokenCollateral, challengePeriodSeconds, _targets, _values, _payloads, address(this));
proposals[_proposalId] = prop;
emit ProposalCreated(_proposalId, address(prop));
}

// it could be interface based for more assets support
function sendErc20(bytes memory proposalId, address tokenAddress, address to, uint256 amount) external {
IProposal proposal = proposals[proposalId];
require(address(proposal) != address(0), "Proposal does not exist");
bool isProposalPassed = proposal.isPassed();
require(isProposalPassed == true, "Proposal did not pass");
IERC20 token = IERC20(tokenAddress);
require(token.transfer(to, amount), "ERC20 transfer failed");
}

function sendNft(bytes memory proposalId, address tokenAddress, address to, uint256 tokenId) external {
IProposal proposal = proposals[proposalId];
require(address(proposal) != address(0), "Proposal does not exist");
bool isProposalPassed = proposal.isPassed();
require(isProposalPassed == true, "Proposal did not pass");
IERC721 token = IERC721(tokenAddress);
token.transferFrom(address(this), to, tokenId);
}

}
10 changes: 0 additions & 10 deletions contracts/DAOCore.sol

This file was deleted.

11 changes: 0 additions & 11 deletions contracts/DaoTimelockController.sol

This file was deleted.

32 changes: 32 additions & 0 deletions contracts/ERC20DAO.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
pragma solidity ^0.8.18;

import "./IProposal.sol";
import "./Proposal.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./ERC20DAOPool.sol";

contract ERC20DAO is DAO {

ERC20DAOPool private daoPool;

// DAO token address
address private tokenAddress;

constructor(address _daoTokenAddress, uint256 _tokenCollateral, uint256 _challengePeriod, uint256 _nativeCollateral)
DAO(_tokenCollateral, _challengePeriod, _nativeCollateral) {
daoPool = new ERC20DAOPool(_daoTokenAddress, address(this), 30 days);
}

function validateTokenCollateral(address userAddress, uint256 requiredCollateral) override public returns (uint256) {
IERC20 token = IERC20(tokenAddress);
return daoPool.balanceOf(msg.sender) / requiredCollateral;
}

function voteWithDaoToken(address proposalAddress, bool vote) override public {
return daoPool.vote(proposalAddress, vote);
}

}
84 changes: 84 additions & 0 deletions contracts/ERC20DAOPool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./Proposal.sol";

contract ERC20DAOPool {

IERC20 private token;
address private daoAddress;
uint256 private _withdrawTimelock;
mapping(address => uint256) private balances;
mapping(address => uint256) public withdrawTimelocks;
mapping(address => address[]) public proposalForVotes;
mapping(address => address[]) public proposalAgainstVotes;

event TokensDeposited(address indexed user, address indexed tokenAddress, uint256 amount);
event TokensWithdrawn(address indexed user, address indexed tokenAddress, uint256 amount, address indexed withdrawAddress);

constructor(address _tokenAddress, address _daoAddress, uint256 _withdrawTimelock) {
token = IERC20(_tokenAddress);
}

function unlock(uint256 amount) public {
IERC20 token = IERC20(token);
withdrawTimelocks[msg.sender] = block.timestamp + _withdrawTimelock;
}

function lockup() public {
delete withdrawTimelocks[msg.sender];
}

function deposit(uint256 amount) public {
require(token.approve(address(this), amount), "Approval failed");
require(token.transferFrom(msg.sender, address(this), amount), "Transfer failed");
balances[msg.sender] += amount;
emit TokensDeposited(msg.sender, address(token), amount);
}

function withdraw(uint256 amount, address withdrawAddress) public {
require(withdrawTimelocks[msg.sender] != 0, "Withdraw locked");
require(withdrawTimelocks[msg.sender] <= block.timestamp, "Withdraw not unlocked yet");
require(balances[msg.sender] >= amount, "Insufficient balance");
require(token.transferFrom(address(this), withdrawAddress, amount), "Transfer failed");
balances[msg.sender] -= amount;
if (balances[msg.sender] == 0) {
delete balances[msg.sender];
delete withdrawTimelocks[msg.sender];
}
emit TokensWithdrawn(msg.sender, address(token), amount, withdrawAddress);
}

function vote(address proposalAddress, bool vote) public {
require(balanceOf(msg.sender) >= 0, "Insufficient balance");
if (vote) {
proposalForVotes[proposalAddress].push(msg.sender);
} else {
proposalAgainstVotes[proposalAddress].push(msg.sender);
}
}

function resolveProposal(address _proposalAddress) public {
Proposal proposal = Proposal(_proposalAddress);
require(proposal.isEnded(), "Proposal not ended");
address[] memory voters = proposal.isPassed() ? proposalForVotes[_proposalAddress] : proposalAgainstVotes[_proposalAddress];
uint256 toTransferAmount = 0;
for (uint256 i = 0; i < voters.length; i++) {
address voterAddress = voters[i];
toTransferAmount += balanceOf(voterAddress);
delete balances[voterAddress];
token.transfer(daoAddress, toTransferAmount);
}
if (proposal.isPassed()) {
delete proposalForVotes[_proposalAddress];
} else {
delete proposalAgainstVotes[_proposalAddress];
}
}

function balanceOf(address account) public view returns (uint256) {
if (withdrawTimelocks[account] != 0) {
return 0;
}
return balances[account];
}

}
11 changes: 11 additions & 0 deletions contracts/ERC20Development.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract ERC20Development is ERC20 {


constructor(string memory _name, string memory _symbol, uint256 _totalSupply) ERC20(_name, _symbol) {
_mint(msg.sender, _totalSupply);
}
}
11 changes: 0 additions & 11 deletions contracts/ERC20GovernanceToken.sol

This file was deleted.

30 changes: 30 additions & 0 deletions contracts/ERC721Development.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
pragma solidity ^ 0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract ERC721Development is ERC721 {

using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
string private baseUri;

constructor() ERC721("DevelopmentNFT", "DNFT") {}

function createNFT(address recipient, string memory baseUri) external returns (uint256) {
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
_mint(recipient, newTokenId);
return newTokenId;
}

function _baseURI() internal view override(ERC721) returns (string memory) {
return baseUri;
}

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);

return 'ipfs://bafybeigs2gea5bauuru4cnec4y5qbitx3a5f73fqx3oo3hwdjtmnis2iny/7610.json';
}
}
12 changes: 0 additions & 12 deletions contracts/ERC721GovernanceToken.sol

This file was deleted.

88 changes: 0 additions & 88 deletions contracts/Governor.sol

This file was deleted.

Loading

0 comments on commit 833d012

Please sign in to comment.