-
-
Save alexvandesande/14ac3d15fc955b56ca40ab278b91cf7a to your computer and use it in GitHub Desktop.
contract HardForkVote { | |
/* | |
There is a very important debate on the Ethereum Community on either | |
contracts should be truly immutable, or if there should be a social | |
consensus that allows some to be changed on extreme circunstances. | |
This contract allows the network to signal support for the decision | |
by having those in favor of a change commit not to move any funds | |
for a year, to prove their long term commitment to the project. | |
*/ | |
// This variable can only be changed by a hard fork. | |
// If no hard fork is in place it will stay at 0; | |
uint public networkId = 0; | |
// This variable sets the date of the vote | |
uint public dateOfDecision; | |
// This keeps the balance of voters | |
mapping (address => mapping (uint => uint)) public votes; | |
function HardForkVote() { | |
// The decision takes place 30 days after this contract is uploaded | |
dateOfDecision = now + 30 days; | |
} | |
function vote(uint supportedNetwork) { | |
// add the amount sent to the vote | |
votes[msg.sender][supportedNetwork] += msg.value; | |
} | |
function withdraw(uint supportedNetwork) { | |
// If the decision date has arrived and you voted for it don't allow withdrawals | |
if (supportedNetwork == networkId | |
&& (now > dateOfDecision - 1 days && now < dateOfDecision + 1 years)) | |
throw; | |
// check the current balance | |
uint balance = votes[msg.sender][supportedNetwork]; | |
// makes it zero to prevent recursion | |
votes[msg.sender][supportedNetwork] = 0; | |
// withdraws | |
msg.sender.send(balance); | |
} | |
function () { | |
throw; | |
} | |
} |
Not only should line 29 use supportedNetwork
instead of networkId
as pointed out by @chevdor, but lines 39 and 42 as well.
Take the scenario that someone votes against a hard fork (by voting for network 0). Then the network hard forks and updates networkId
to be 1. Now the person would have no way of withdrawing their ether. But if lines 39 and 42 were updated, then the person could withdraw their ether.
@AustP I was think about that too but I guess the idea of @alexvandesande is that only the funds on the legit fork can be withdrawn and not the rest. If that´s the case, the contract is ok. That´s a bit mean though :)
If this is not the case and we agree that everyone should be able to get back his money, just after 1 year, then you are right and the contract should be fixed.
I don´t want to speak for him though.
It seems that, even if the code is clear, the intend of the contract´s author may not.
If the ETH of the 'loser' bets is lost, why not splitting (I feel I should stay away from that word for a while) or sending it as bonus between the users who supported the right fork :) ? That would be an incentive to voting but once again, I think the goal of the contract was not to implement a betting game but to show serious support to an option or another.
An issue I see as well is: how can we be sure of what the networkId will be in a year?
It could be 0 or 1 but also anything else in case of other forks...
I would also probably change the part around line 34 into something less ambiguous to read such as:
if (supportedNetwork != networkId)
throw;
if (now > dateOfDecision - 1 days && now < dateOfDecision + 3 days))
throw;
additionally, I am not sure if the "now > dateOfDecision - 1 days" brings much since we just want to lock until the 1y date is reached.
But I guess this is already going too far as Alex probably just wanted to illustrate the idea.
I just fixed some of the issues because I deployed to testnet and wanted to have something working.
As your ether is going to be stuck for one year, you will not be able to participate again in another vote in that period.
In the end, reading such contract is way quicker than a reddit :)
Well done and thanks for sharing. I fixed however a rather big bug. In your version, the votes all go to the CURRENT network instead of the voted one.
I modified also very slightly and deployed it to morden with short time locks (few days max just for testing).
On morden: 0x6fAfCc0F809be60Ad996F7326315Db177D9550Bf
Json Interface:
[{"constant":false,"inputs":[{"name":"supportedNetwork","type":"uint256"}],"name":"vote","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"supportedNetwork","type":"uint256"}],"name":"withdraw","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"dateOfDecision","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"networkId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"votes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[],"type":"constructor"}]
Deployed contract: