-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
3,269 additions
and
1,757 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.