PatrickAlphaC / dao-template

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Questions on Expanding on Your DAO Template

codesport opened this issue · comments

Hi @PatrickAlphaC

Thank you for this helpful tutorial!

I'm leveling-up my Solidity skills and learning about DAOs using OpenZeppelin's standards! So, these are just questions on how to build upon your template and not issues.

  1. Is some sort of "gatekeeper" function needed to only allow holders of the token to make proposals and to vote? Or is this built into ERC20Votes.sol? My actual use-case is draft-ERC721Votes.sol .

  2. What would be the purpose of ADDRESS_ZERO in the config and setup files? Is this to save gas?

  3. It's mentioned that TimeLock.sol handles all the money, ownerships, etc

    • How would this apply to the following use-case? If you want (i) to charge for your token and (ii) store those received funds in your DAO's Treasury, wouldn't this all be inside your token minter contract, that is, GovernanceToken.sol and not in TimeLock.sol?
  1. Nope! The way this is set up, anyone can make a proposal.
  2. We setup the executor of a proposal like this:
    const executorTx = await timeLock.grantRole(executorRole, ADDRESS_ZERO)

This makes it so that once a proposal has:

  1. Been proposed
  2. Passed the vote
  3. Passed the time lock period

Anyone can "execute" the proposal.

  1. Not quite.
    You'd still want the timelock controller to own your treasury wallet. You could put some functionality of payment in the GT contract, but I think it would make more sense for the timelock controller contract to own all the GT tokens and just make people pay for them (if that's what you want to do)

Thank you @PatrickAlphaC

Your Answers are very thorough and educational.

Just some clarifying followups.

So anyone can propose, but only token holders may vote. So is it safe to assume the chain of imported contracts from GovernorContract.sol and ERCXXVotes.sol ensure that only valid token holders can vote?

Linking Contracts

I noticed there was no special solidity code to somehow 'link" these 3 contracts. So this linking is only handled within our deployment scripts? However, I do know OpenZeppelin's Ownable and onlyOwner directive does allow an owner to be specified and customized.

In conclusion, the linkages are through the contract deployer (me) or whatever contract is designated as the Owner using Ownable.sol

Treasury Wallet
Is the "Treasury Wallet" typically a separate contract or do we typically leave the funds in the contract that mints the tokens? Or do we make TimeLock.sol the "Treasury Wallet"? I'm not quite sure what is a best practice.

I guess no matter which contract serves as the Treasury Wallet, some sort of payable and receiver functionality is needed in its solidity code.

Time Lock
I think I may understand now. It's best practice for only TimeLock.sol to deposit and withdraw funds from that Treasury wallet/contract. Being a DAO, this ensures that funds are only moved by the democratic consensus of its members.

Do you recommend importing Ownable.sol into the TimeLock.sol? Or only into GovernorToken.sol and GovernorContract.sol?

So anyone can propose, but only token holders may vote. So is it safe to assume the chain of imported contracts from GovernorContract.sol and ERCXXVotes.sol ensure that only valid token holders can vote?

Yes.

I noticed there was no special solidity code to somehow 'link" these 3 contracts.

There is:

This "links" the governance token of choice to the governor contract:

This "links" the governor contract to the timelock:

const proposerTx = await timeLock.grantRole(proposerRole, governor.address)

Treasury Wallet
The treasury wallet can simply be the timelock contract.

Do you recommend importing Ownable.sol into the TimeLock.sol? Or only into GovernorToken.sol and GovernorContract.sol?

Neither. All the permissions are handled inside the contracts imported already.

@PatrickAlphaC Thank you again.

It all makes a lot more sense now!