Skip to content

Commit

Permalink
feat: add beginning of superfluid token
Browse files Browse the repository at this point in the history
  • Loading branch information
SloWayyy committed Jun 26, 2023
1 parent 5104a7b commit 3a6d058
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 68 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "dao/lib/openzeppelin-contracts"]
path = dao/lib/openzeppelin-contracts
url = https://github.com/Openzeppelin/openzeppelin-contracts
[submodule "dao/lib/superfluid-protocol-monorepo"]
path = dao/lib/superfluid-protocol-monorepo
url = https://github.com/superfluid-finance/protocol-monorepo
1 change: 1 addition & 0 deletions dao/lib/superfluid-protocol-monorepo
1 change: 1 addition & 0 deletions dao/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
@openzeppelin/=lib/openzeppelin-contracts/
@superfluid-finance/=lib/superfluid-protocol-monorepo/
33 changes: 0 additions & 33 deletions dao/src/SuperFluidToken.sol

This file was deleted.

32 changes: 15 additions & 17 deletions dao/src/SuperFluidDao.sol → dao/src/SuperfluidDao.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

// import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol";
import {SuperfluidDaoToken} from "./SuperfluidDaoToken.sol";

import {SuperFluidToken} from "./SuperFluidToken.sol";

interface ISuperFluidDao {
interface ISuperfluidDao {
struct Proposal {
uint256 voteFor;
uint256 voteAgainst;
Expand All @@ -25,8 +23,8 @@ interface ISuperFluidDao {
// error
error InvalidProposalId();
error AlreadyVoted();
error NotEnoughSuperfluidToken();
error ZeroSuperfluidToken();
error NotEnoughSuperfluidDaoToken();
error ZeroSuperfluidDaoToken();
error ProposalAlreadyExecuted();
error ProposalDueDateNotReached();
error ProposalDueDatePassed();
Expand All @@ -43,7 +41,7 @@ interface ISuperFluidDao {
// functions
function postProposal(bytes32 descriptionCID, uint64 timeSpan) external;

function getToken() external view returns (SuperFluidToken);
function getToken() external view returns (SuperfluidDaoToken);

function getProposal(
uint _proposalId
Expand All @@ -52,13 +50,13 @@ interface ISuperFluidDao {
function getProposals() external view returns (Proposal[] memory);
}

contract SuperFluidDao is ISuperFluidDao {
contract SuperfluidDao is ISuperfluidDao {
mapping(address => mapping(uint256 => VoteStatus)) private _votes;
Proposal[] private _proposals;
SuperFluidToken private _superFluidToken;
SuperfluidDaoToken private _superfluidToken;

constructor() {
_superFluidToken = new SuperFluidToken();
_superfluidToken = new SuperfluidDaoToken();
}

function postProposal(bytes32 descriptionCID, uint64 timeSpan) public {
Expand All @@ -77,8 +75,8 @@ contract SuperFluidDao is ISuperFluidDao {
emit ProposalSubmitted(_proposals.length - 1);
}

function getToken() public view returns (SuperFluidToken) {
return _superFluidToken;
function getToken() public view returns (SuperfluidDaoToken) {
return _superfluidToken;
}

function getProposal(
Expand All @@ -105,10 +103,10 @@ contract SuperFluidDao is ISuperFluidDao {
revert ProposalDueDatePassed();
}

uint256 voteWeight = _superFluidToken.balanceOf(msg.sender);
uint256 voteWeight = _superfluidToken.balanceOf(msg.sender);

if (voteWeight == 0) {
revert ZeroSuperfluidToken();
revert ZeroSuperfluidDaoToken();
}

if (voteChoice) {
Expand All @@ -119,7 +117,7 @@ contract SuperFluidDao is ISuperFluidDao {
_votes[msg.sender][proposalId] = VoteStatus.VotedAgainst;
}

_superFluidToken.burn(msg.sender, 1);
_superfluidToken.burn(msg.sender, 1);

emit CastVote(msg.sender, proposalId, voteWeight);
}
Expand All @@ -141,10 +139,10 @@ contract SuperFluidDao is ISuperFluidDao {
_proposals[proposalId].executed = true;

if (_proposals[proposalId].voteFor > _proposals[proposalId].voteAgainst) {
_superFluidToken.mint(msg.sender, _proposals[proposalId].voteFor);
_superfluidToken.mint(msg.sender, _proposals[proposalId].voteFor);
}
if (_proposals[proposalId].voteFor < _proposals[proposalId].voteAgainst) {
_superFluidToken.burn(msg.sender, 1);
_superfluidToken.burn(msg.sender, 1);
}
}
}
46 changes: 46 additions & 0 deletions dao/src/SuperfluidDaoToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { ISuperfluid } from "@superfluid-finance/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import { IConstantFlowAgreementV1 } from "@superfluid-finance/packages/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol";
import { ISuperToken } from "@superfluid-finance/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol";
import { ISuperfluidToken } from "@superfluid-finance/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol";

contract SuperfluidAdmin {
address private _admin;

constructor() {
_admin = msg.sender;
}

modifier onlyAdmin() {
require(msg.sender == _admin, "SuperfluidAdmin/NotAuthorized");
_;
}

function setAdmin(address admin) public onlyAdmin {
_admin = admin;
}
}

contract SuperfluidDaoToken is ERC20, SuperfluidAdmin {

// ISuperfluid private _host; // Contrat hôte Superfluid
// IConstantFlowAgreementV1 private _cfa; // Contrat d'accord de flux constant
// ISuperToken private _superToken; // Contrat Super Token

constructor() ERC20("SuperfluidDaoToken", "SFT") SuperfluidAdmin() {
// _host = ISuperfluid(msg.sender)
// _cfa = IConstantFlowAgreementV1();
// _superToke
}

function mint(address to, uint256 amount) public onlyAdmin {
_mint(to, amount);
}

function burn(address to, uint256 amount) public onlyAdmin {
_burn(to, amount);
}
}
36 changes: 18 additions & 18 deletions dao/test/SuperFluidDao.t.sol → dao/test/SuperfluidDao.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/SuperFluidDao.sol";
import {SuperFluidToken} from "../src/SuperFluidToken.sol";
import "../src/SuperfluidDao.sol";
import {SuperfluidDaoToken} from "../src/SuperfluidDaoToken.sol";

contract SuperFluidDaoTest is Test {
contract SuperfluidDaoTest is Test {

address Isma = vm.addr(0x1);
SuperFluidDao Dao;
SuperfluidDao Dao;

function setUp() public {
Dao = new SuperFluidDao();
Dao = new SuperfluidDao();
}

function mintTo(address to, uint256 amount) public {
vm.startPrank(address(Dao));
SuperFluidToken token = Dao.getToken();
SuperfluidDaoToken token = Dao.getToken();
token.mint(to, amount);
vm.stopPrank();
}
Expand All @@ -27,15 +27,15 @@ contract SuperFluidDaoTest is Test {
}

function test_VoteInvalidProposalId() public {
vm.expectRevert(ISuperFluidDao.InvalidProposalId.selector);
vm.expectRevert(ISuperfluidDao.InvalidProposalId.selector);
Dao.vote(0, true);
}

function test_VoteProposalAlreadyExecuted() public {
vm.startPrank(Isma);
Dao.postProposal("Donnez moins d'argent a Isma", 0);
Dao.executeProposal(0);
vm.expectRevert(ISuperFluidDao.ProposalAlreadyExecuted.selector);
vm.expectRevert(ISuperfluidDao.ProposalAlreadyExecuted.selector);
Dao.vote(0, true);
vm.stopPrank();
}
Expand All @@ -45,7 +45,7 @@ contract SuperFluidDaoTest is Test {
Dao.postProposal("Donnez moins d'argent a Isma", 10);
vm.startPrank(Isma);
Dao.vote(0, false);
vm.expectRevert(ISuperFluidDao.AlreadyVoted.selector);
vm.expectRevert(ISuperfluidDao.AlreadyVoted.selector);
Dao.vote(0, false);
vm.stopPrank();
}
Expand All @@ -54,15 +54,15 @@ contract SuperFluidDaoTest is Test {
mintTo(Isma, 2);
Dao.postProposal("Donnez moins d'argent a Isma", 0);
vm.startPrank(Isma);
vm.expectRevert(ISuperFluidDao.ProposalDueDatePassed.selector);
vm.expectRevert(ISuperfluidDao.ProposalDueDatePassed.selector);
Dao.vote(0, true);
vm.stopPrank();
}

function test_VoteZeroSuperfluidToken() public {
function test_VoteZeroSuperfluidDaoToken() public {
Dao.postProposal("Donnez moins d'argent a Isma", 10);
vm.startPrank(Isma);
vm.expectRevert(ISuperFluidDao.ZeroSuperfluidToken.selector);
vm.expectRevert(ISuperfluidDao.ZeroSuperfluidDaoToken.selector);
Dao.vote(0, true);
vm.stopPrank();
}
Expand All @@ -72,37 +72,37 @@ contract SuperFluidDaoTest is Test {
vm.startPrank(Isma);
Dao.postProposal("Donnez moins d'argent a Isma", 10);
Dao.vote(0, true);
ISuperFluidDao.Proposal memory proposal = Dao.getProposal(0);
ISuperfluidDao.Proposal memory proposal = Dao.getProposal(0);
assertEq(proposal.voteFor, 1);
vm.stopPrank();
}

function test_ExecuteProposalInvalidProposalId() public {
vm.expectRevert(ISuperFluidDao.InvalidProposalId.selector);
vm.expectRevert(ISuperfluidDao.InvalidProposalId.selector);
Dao.executeProposal(0);
}

function test_ExecuteProposalProposalAlreadyExecuted() public {
vm.startPrank(Isma);
Dao.postProposal("Donnez moins d'argent a Isma", 0);
Dao.executeProposal(0);
vm.expectRevert(ISuperFluidDao.ProposalAlreadyExecuted.selector);
vm.expectRevert(ISuperfluidDao.ProposalAlreadyExecuted.selector);
Dao.executeProposal(0);
vm.stopPrank();
}

function test_ExecuteProposalProposalDueDateNotReached() public {
vm.startPrank(Isma);
Dao.postProposal("Donnez moins d'argent a Isma", 100000000000);
vm.expectRevert(ISuperFluidDao.ProposalDueDateNotReached.selector);
vm.expectRevert(ISuperfluidDao.ProposalDueDateNotReached.selector);
Dao.executeProposal(0);
vm.stopPrank();
}

function test_ExecuteProposalProposalExecutedByNonAuthor() public {
Dao.postProposal("Donnez moins d'argent a Isma", 0);
vm.startPrank(Isma);
vm.expectRevert(ISuperFluidDao.ProposalExecutedByNonAuthor.selector);
vm.expectRevert(ISuperfluidDao.ProposalExecutedByNonAuthor.selector);
Dao.executeProposal(0);
vm.stopPrank();
}
Expand All @@ -112,7 +112,7 @@ contract SuperFluidDaoTest is Test {
vm.startPrank(Isma);
Dao.postProposal("Donnez moins d'argent a Isma", 1);
Dao.vote(0, true);
ISuperFluidDao.Proposal memory proposal = Dao.getProposal(0);
ISuperfluidDao.Proposal memory proposal = Dao.getProposal(0);

while (block.timestamp >= proposal.dueDate)

Expand Down

0 comments on commit 3a6d058

Please sign in to comment.