DAO should be able to raise funds through a Voting process
uivlis opened this issue · comments
The goal is to be able to restart the DAO funding through a Voting, much like when proposing a new venture, or releasing dividends.
However, that would require the DAO (or the Voting?) to call on the DAO itself several methods from IssuanceEth
(for example, setIssuePrice
, or startDistribution
etc.) which can be called only by the owner (the deployer of the DAO, that is).
This task is also to find a possible solution to this dilemma.
One way of bypassing the issue would be to have the owner call on the DAO transferOwnership
to the DAO once the DAO is launched.
I think that transferring ownership to the DAO contract is an elegant solution.
Once that is done we can put all actions through votes.
To allow the several functions to be called we can put them all together in a DAO function, when they all can be executed in the same transaction (for example transition
, setIssuePrice
and startIssuance
).
We probably should also allow the DAO to accept proposals with arbitrary proposalData
, so that a proposal can be done for any single function and parameter combination in the DAO contract. Instead of proposeVenture
and proposeDividends
we would have propose(contractAddress, proposalData)
Thoughts @uivlis?
Sure, I'll do this.
And I think there might be an even more elegant solution for the ownership issue, that does not require any call on behalf of the owner, but that will be a surprise (because I'm not sure it will work).
I've been thinking about your suggestion of having propose(address, data)
replace all the other propose functions, but I see some major setbacks: it would require participants to manually check (if it's available) the contract code of every proposal in order to know what they are voting for. It would also make room for memory abuse of the proposals
storage variable. Should we better stay with individuated propose functions? After all, we still have to keep the individuated enacting functions in the DAO.
Oh, and regarding that surprise: I was thinking at calling address(this).delegatecall(abi.encodeWithSignature("transferOwnership(address)", address(this)));
inside the DAO
constructor, apparently it works. However, that would mean that I have to override setIssuePrice
, startIssuance
and so on for the initial round since now, only the DAO could call these functions and there's no voting since there are no tokens, yet. So I would do this:
function startDistribution() public {
require(
totalSupply() == 0 || proposals.contains(msg.sender),
"Could not start distribution."
);
super.startDistribution();
proposals.remove(msg.sender);
}
for example, which would work both for the initial round, and for future voted rounds.
Let me know your thought on these.
Oh, and regarding that surprise: I was thinking at calling address(this).delegatecall(abi.encodeWithSignature("transferOwnership(address)", address(this))); inside the DAO constructor, apparently it works.
-
Can't you just call
transferOwnership(address(this))
in the constructor (link)? -
While that is a cool idea, wouldn't be cleaner to
transferOwnership
insidestartDistribution
? To mee it seems like the point in time when the DAO actually comes to life. During the initial funding round the DAO doesn't actually exist, it's only a proposal (coded as an issuance process). -
I'm thinking of getting rid of
setIssuePrice
and take price as a constructor parameter (inheriting contracts can create a function to reset the issue price if they need to).
-
No, I don't think so, since
transferOwnership
has to be called by the owner, that's why I usedelegatecall
. -
Yes.
-
Should I do this in
Issuance
?
- Interesting.
- Let's try in
startDistribution
then. - Yes, please remove from
Issuance
I just merged #226, please start a new branch from master
for this issue.
I've been thinking at another issue. When opening a new investment round, the startDistribution
call must be voted (as the DAO is now the owner, after the initial phase), as well as in the case of cancelAllInvestments
, which made me think at this: why do we need the states in Issuances? That is, why can't we just have invest and claim and cancel called haphazardly? It would simplify a lot, not just the DAO, but also the Issuance.
invest
cannot be called at will, because that would allow anyone to mint more issuance tokens at the ICO price, regardless of the market price.
cancelAllInvestments
can be simply removed from IssuanceEth.sol
, IMHO.
To remove startDistribution
we could modify IssuanceEth.sol
so that it takes a targetAmount
at the constructor, and then invest
checks msg.value
:
amountRaised + msg.value < targetAmount
-> ContinueamountRaised + msg.value > targetAmount
-> RevertamountRaised + msg.value = targetAmount
->_transition("LIVE")
The latest one would be hard to achieve if the gas used is removed from msg.value (is it?).
In plain English this issuance would be "I want to raise this much, if I get it go live immediately.". If the funds are not raised the issuance would be come a kind of zombie.
I'm not too bothered about changing the mechanics of IssuanceEth
as long as we keep it a simple contract.