Dao11 #228
fe5828a
255e97e
a717689
d7aa20f
3be9f85
c72d38f
12961ee
3847ade
130d0c8
e5da4ba
a47decf
38e0ecc
a1f6197
df13bd2
17a8a2c
bc470f7
9bccc0c
85f2088
b7f48c6
14be66d
c68dba5
328f515
| @@ -43,6 +43,10 @@ contract DAOInterface { | ||
| // Denotes the maximum proposal deposit that can be given. It is given as | ||
| // a fraction of total Ether spent plus balance of the DAO | ||
| uint constant maxDepositDivisor = 100; | ||
| + // Grace period for splitting after voting did end | ||
| + uint constant splitGracePeriod = 3 days; | ||
| + // Time for vote freeze. A proposal needs to have majority support before votingDeadline - preSupportTime | ||
| + uint constant preSupportTime = 2 days; | ||
| // Proposals to spend the DAO's ether or to choose a new Curator | ||
| Proposal[] public proposals; | ||
| @@ -82,6 +86,9 @@ contract DAOInterface { | ||
| // tokens). The address points to the proposal ID. | ||
| mapping (address => uint) public blocked; | ||
| + // Map of addresses and proposal voted on by this address | ||
| + mapping (address => uint[]) public votingRegister; | ||
| + | ||
| // The minimum deposit (in wei) required to submit any proposal that is not | ||
| // requesting a new Curator (no deposit is required for splits) | ||
| uint public proposalDeposit; | ||
| @@ -121,6 +128,13 @@ contract DAOInterface { | ||
| bool newCurator; | ||
| // Data needed for splitting the DAO | ||
| SplitData[] splitData; | ||
| + // Dependencies in other proposals. List of proposal IDs and list defining | ||
| + // whether the other proposal needs to have passed or failed | ||
| + uint[] dependentProposalIDs; | ||
| + bool[] dependencyShouldPass; | ||
| + // true if more tokens are in favour of the proposal than opposed to it at | ||
| + // least `preSupportTime` before the voting deadline | ||
| + bool preSupport; | ||
| // Number of Tokens in favor of the proposal | ||
| uint yea; | ||
| // Number of Tokens opposed to the proposal | ||
| @@ -206,7 +220,9 @@ contract DAOInterface { | ||
| string _description, | ||
| bytes _transactionData, | ||
| uint _debatingPeriod, | ||
| - bool _newCurator | ||
| + bool _newCurator, | ||
| + uint[] dependentProposalIDs, | ||
| + bool[] dependencyShouldPass | ||
| ) onlyTokenholders returns (uint _proposalID); | ||
| /// @notice Check that the proposal with the ID `_proposalID` matches the | ||
| @@ -337,7 +353,8 @@ contract DAOInterface { | ||
| address recipient, | ||
| uint amount, | ||
| bool newCurator, | ||
| - string description | ||
| + string description, | ||
| + bytes transactionData | ||
| ); | ||
| event Voted(uint indexed proposalID, bool position, address indexed voter); | ||
| event ProposalTallied(uint indexed proposalID, bool result, uint quorum); | ||
| @@ -382,7 +399,7 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| if (address(DAOrewardAccount) == 0) | ||
| throw; | ||
| lastTimeMinQuorumMet = now; | ||
| - minQuorumDivisor = 5; // sets the minimal quorum to 20% | ||
| + minQuorumDivisor = 7; // sets the minimal quorum to 14.2% | ||
| proposals.length = 1; // avoids a proposal with ID 0 because it is used | ||
| allowedRecipients[address(this)] = true; | ||
| @@ -408,10 +425,16 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| string _description, | ||
| bytes _transactionData, | ||
| uint _debatingPeriod, | ||
| - bool _newCurator | ||
| + bool _newCurator, | ||
| + uint[] _dependentProposalIDs, | ||
| + bool[] _dependencyShouldPass | ||
| ) onlyTokenholders returns (uint _proposalID) { | ||
| // Sanity check | ||
| + | ||
| + if (_dependentProposalIDs.length != _dependencyShouldPass.length) | ||
| + throw; | ||
| + | ||
| if (_newCurator && ( | ||
| _amount != 0 | ||
| || _transactionData.length != 0 | ||
| @@ -421,16 +444,15 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| throw; | ||
| } else if ( | ||
| !_newCurator | ||
| - && (!isRecipientAllowed(_recipient) || (_debatingPeriod < minProposalDebatePeriod)) | ||
| + && (!allowedRecipients[_recipient] || (_debatingPeriod < minProposalDebatePeriod)) | ||
| ) { | ||
| throw; | ||
| } | ||
| if (_debatingPeriod > 8 weeks) | ||
| throw; | ||
| - if (!isFueled | ||
| - || now < closingTime | ||
| + if (now < closingTime | ||
| || (msg.value < proposalDeposit && !_newCurator)) { | ||
| throw; | ||
| @@ -461,6 +483,8 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| p.splitData.length++; | ||
| p.creator = msg.sender; | ||
| p.proposalDeposit = msg.value; | ||
| + p.dependentProposalIDs = _dependentProposalIDs; | ||
| + p.dependencyShouldPass = _dependencyShouldPass; | ||
| sumOfProposalDeposits += msg.value; | ||
| @@ -469,7 +493,8 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| _recipient, | ||
| _amount, | ||
| _newCurator, | ||
| - _description | ||
| + _description, | ||
| + _transactionData | ||
| ); | ||
| } | ||
| @@ -487,13 +512,12 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| function vote(uint _proposalID, bool _supportsProposal) onlyTokenholders noEther { | ||
| + if (DAO(parentDAO).balanceOf(msg.sender) != 0) | ||
| + swapTokens(); | ||
| + | ||
| Proposal p = proposals[_proposalID]; | ||
| - if (p.votedYes[msg.sender] | ||
| - || p.votedNo[msg.sender] | ||
| - || now >= p.votingDeadline) { | ||
| - throw; | ||
| - } | ||
| + unVote(_proposalID); | ||
| if (_supportsProposal) { | ||
| p.yea += balances[msg.sender]; | ||
| @@ -511,9 +535,56 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| blocked[msg.sender] = _proposalID; | ||
| } | ||
| + votingRegister[msg.sender].push(_proposalID); | ||
| Voted(_proposalID, _supportsProposal, msg.sender); | ||
| } | ||
| + function unVote(uint _proposalID){ | ||
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
|
||
| + Proposal p = proposals[_proposalID]; | ||
| + | ||
| + if (now >= p.votingDeadline) { | ||
| + throw; | ||
| + } | ||
| + | ||
| + if ((p.votedYes[msg.sender] | ||
| + || p.votedNo[msg.sender]) | ||
| + && now > p.votingDeadline - preSupportTime) { | ||
| + throw; | ||
| + } | ||
| + | ||
| + if (p.votedYes[msg.sender]) { | ||
| + p.yea -= balances[msg.sender]; | ||
| + p.votedYes[msg.sender] = false; | ||
| + } | ||
| + | ||
| + if (p.votedNo[msg.sender]) { | ||
| + p.nay -= balances[msg.sender]; | ||
| + p.votedNo[msg.sender] = false; | ||
| + } | ||
| + } | ||
| + | ||
| + function unVoteAll() { | ||
| + for (uint i = 0; i < votingRegister[msg.sender].length; i++) { | ||
| + Proposal p = proposals[votingRegister[msg.sender][i]]; | ||
| + if (now < p.votingDeadline) | ||
| + unVote(i); | ||
| + } | ||
| + | ||
| + votingRegister[msg.sender].length = 0; | ||
| + blocked[msg.sender] = 0; | ||
| + } | ||
| + | ||
| + function verifyPreSupport(uint _proposalID) { | ||
| + Proposal p = proposals[_proposalID]; | ||
| + if (now < p.votingDeadline - preSupportTime) { | ||
| + if (p.yea > p.nay) { | ||
|
Maybe add a I think it is enough that we don't count the nay votes in the real quorum. Same one as I used for PFOffer.sol. I can call At a later state someone else may call it to change it back to false if yea and nay are in a very close fight. But if they don't, then the As you said, the function can be called again and again to update the result, until I think there's an issue with unvote() if you don't keep state of their original balance[voter] used to increment yea or nay votes. Here's the scenario: 1) balances[voter] is currently 100 Perhaps we can use Proposal.yesVote[voter] and Proposal.votedNo[voter] can be used to keep state of their original voting balance[voter] instead of as a bool. Thoughts? @cougarously: No we don't need this because we are now also stopping people from transferring tokens to blocked addresses. so in your scenario step (3) would fail. @LefterisJP - Ah okay! I see that there is DAO.transfer and DAO.transferFrom() that overrides the ones in Token. How about this scenario. I have a voted on many proposals that are currently still active. One of those proposals is a split proposal and I split and I'm not part of the DAO anymore but I have influence on the proposals that are still active. Should this be allowed? If not (which I believe is the case), we need to unvoteAll() when burning their tokens in splitDAO() and withdraw(). So here's what may need to be done: 1) add the modifier onlyTokenholders to unvote() and unvoteAll() Thats already the case. In splitDAO and withdraw
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
|
||
| + p.preSupport = true; | ||
| + } | ||
| + else | ||
| + p.preSupport = false; | ||
| + } | ||
| + } | ||
| + | ||
| function executeProposal( | ||
| uint _proposalID, | ||
| @@ -526,13 +597,14 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| ? splitExecutionPeriod | ||
| : executeProposalPeriod; | ||
| // If we are over deadline and waiting period, assert proposal is closed | ||
| - if (p.open && now > p.votingDeadline + waitPeriod) { | ||
| + if (p.open && now > p.votingDeadline + splitGracePeriod + waitPeriod) { | ||
| closeProposal(_proposalID); | ||
| return; | ||
| } | ||
| // Check if the proposal can be executed | ||
| - if (now < p.votingDeadline // has the voting deadline arrived? | ||
| + if (!isFueled | ||
| + || now < p.votingDeadline + splitGracePeriod // has the voting deadline arrived? | ||
| // Have the votes been counted? | ||
| || !p.open | ||
| || p.proposalPassed // anyone trying to call us recursively? | ||
| @@ -542,22 +614,29 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| throw; | ||
| } | ||
| + // check dependencies | ||
| + for (uint _p = 0; _p < p.dependentProposalIDs.length; _p++) { | ||
| + Proposal requiredProposal = proposals[p.dependentProposalIDs[_p]]; | ||
| + if (requiredProposal.proposalPassed != p.dependencyShouldPass[_p]) | ||
| + throw; | ||
| + } | ||
| + | ||
| // If the curator removed the recipient from the whitelist, close the proposal | ||
| // in order to free the deposit and allow unblocking of voters | ||
| - if (!isRecipientAllowed(p.recipient)) { | ||
| + if (!allowedRecipients[p.recipient]) { | ||
| closeProposal(_proposalID); | ||
| p.creator.send(p.proposalDeposit); | ||
| return; | ||
| } | ||
| bool proposalCheck = true; | ||
| - if (p.amount > actualBalance()) | ||
| + if (p.amount > actualBalance() || p.preSupport == false) | ||
| proposalCheck = false; | ||
| - uint quorum = p.yea + p.nay; | ||
| + uint quorum = p.yea; | ||
| - // require 53% for calling newContract() | ||
| + // require max quorum for calling newContract() | ||
| if (_transactionData.length >= 4 && _transactionData[0] == 0x68 | ||
| && _transactionData[1] == 0x37 && _transactionData[2] == 0xff | ||
| && _transactionData[3] == 0x1e | ||
| @@ -566,18 +645,20 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| proposalCheck = false; | ||
| } | ||
| - if (quorum >= minQuorum(p.amount)) { | ||
| + uint minimumQuorum = minQuorum(p.amount); | ||
| + | ||
| + if (quorum >= minimumQuorum) { | ||
| if (!p.creator.send(p.proposalDeposit)) | ||
| throw; | ||
| lastTimeMinQuorumMet = now; | ||
| - // set the minQuorum to 20% again, in the case it has been reached | ||
| - if (quorum > totalSupply / 5) | ||
| - minQuorumDivisor = 5; | ||
| + // set the minQuorum to 14.3% again, in the case it has been reached | ||
| + if (quorum > totalSupply / 7) | ||
| + minQuorumDivisor = 7; | ||
| } | ||
| // Execute result | ||
| - if (quorum >= minQuorum(p.amount) && p.yea > p.nay && proposalCheck) { | ||
| + if (quorum >= minimumQuorum && p.yea > p.nay && proposalCheck) { | ||
| // we are setting this here before the CALL() value transfer to | ||
| // assure that in the case of a malicious recipient contract trying | ||
| // to call executeProposal() recursively money can't be transferred | ||
| @@ -593,7 +674,6 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| // related addresses. Proxy addresses should be forbidden by the curator. | ||
| if (p.recipient != address(this) && p.recipient != address(rewardAccount) | ||
| && p.recipient != address(DAOrewardAccount) | ||
| - && p.recipient != address(extraBalance) | ||
| && p.recipient != address(curator)) { | ||
|
Do you think this should be removed: I think what we want to do is move the funds from the extraBalance account to the DAO without incrementing the reward tokens initially. Then when there is a real proposal that requires funding from the DAO, then the reward tokens will be incremented appropriately. In addition to my comment above. How do we actually move funds from the extraBalance to the DAO? If a Proposal's recipient is the DAO itself, then the code in executeProposal() will send funds to itself when executing:
So it seems like we need some special code where the DAO can send a message to the extraBalance account by calling
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
|
||
| rewardToken[address(this)] += p.amount; | ||
| @@ -615,6 +695,46 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| p.open = false; | ||
| } | ||
| + function withdraw( | ||
| + address _newCurator | ||
| + ) noEther onlyTokenholders returns (bool _success) { | ||
| + | ||
| + unVoteAll(); | ||
| + | ||
| + // Move ether | ||
| + uint fundsToBeMoved = | ||
| + (balances[msg.sender] * actualBalance()) / | ||
| + totalSupply; | ||
| + | ||
| + msg.sender.call.value(fundsToBeMoved); | ||
| + | ||
| + // Assign reward rights | ||
| + uint rewardTokenToBeMoved = | ||
| + (balances[msg.sender] * rewardToken[address(this)]) / | ||
| + totalSupply; | ||
| + | ||
| + uint paidOutToBeMoved = DAOpaidOut[address(this)] * rewardTokenToBeMoved / | ||
| + rewardToken[address(this)]; | ||
| + | ||
| + rewardToken[msg.sender] += rewardTokenToBeMoved; | ||
| + if (rewardToken[address(this)] < rewardTokenToBeMoved) | ||
| + throw; | ||
| + rewardToken[address(this)] -= rewardTokenToBeMoved; | ||
| + | ||
| + DAOpaidOut[msg.sender] += paidOutToBeMoved; | ||
| + if (DAOpaidOut[address(this)] < paidOutToBeMoved) | ||
| + throw; | ||
| + DAOpaidOut[address(this)] -= paidOutToBeMoved; | ||
| + | ||
| + // Burn DAO Tokens | ||
| + Transfer(msg.sender, 0, balances[msg.sender]); | ||
| + withdrawRewardFor(msg.sender); // be nice, and get his rewards | ||
| + totalSupply -= balances[msg.sender]; | ||
| + balances[msg.sender] = 0; | ||
| + paidOut[msg.sender] = 0; | ||
| + return true; | ||
| + } | ||
| + | ||
| function splitDAO( | ||
| uint _proposalID, | ||
| address _newCurator | ||
| @@ -632,13 +752,13 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| // Is it a new curator proposal? | ||
| || !p.newCurator | ||
| // Have you voted for this split? | ||
| - || !p.votedYes[msg.sender] | ||
| - // Did you already vote on another proposal? | ||
| - || (blocked[msg.sender] != _proposalID && blocked[msg.sender] != 0) ) { | ||
| + || !p.votedYes[msg.sender]) { | ||
| throw; | ||
| } | ||
| + unVoteAll(); | ||
| + | ||
| // If the new DAO doesn't exist yet, create the new DAO and store the | ||
| // current split data | ||
| if (address(p.splitData[0].newDAO) == 0) { | ||
| @@ -662,7 +782,6 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false) | ||
| throw; | ||
| - | ||
| // Assign reward rights to new DAO | ||
| uint rewardTokenToBeMoved = | ||
| (balances[msg.sender] * p.splitData[0].rewardToken) / | ||
| @@ -755,6 +874,7 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| if (isFueled | ||
| && now > closingTime | ||
| && !isBlocked(msg.sender) | ||
| + && !isBlocked(_to) | ||
| && _to != address(this) | ||
| && transferPaidOut(msg.sender, _to, _value) | ||
| && super.transfer(_to, _value)) { | ||
| @@ -777,6 +897,7 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| if (isFueled | ||
| && now > closingTime | ||
| && !isBlocked(_from) | ||
| + && !isBlocked(_to) | ||
| && _to != address(this) | ||
| && transferPaidOut(_from, _to, _value) | ||
| && super.transferFrom(_from, _to, _value)) { | ||
| @@ -826,32 +947,24 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| function changeAllowedRecipients(address _recipient, bool _allowed) noEther external returns (bool _success) { | ||
| - if (msg.sender != curator) | ||
| + // only allow the curator and the DAO itself (only removing addresses) to make changes to the whitelist | ||
| + if (msg.sender != curator && (msg.sender != address(this) || _allowed)) | ||
|
The second leg of the boolean condition after the && is essentially saying:
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
|
||
| + throw; | ||
| + if (_recipient == address(this)) | ||
| throw; | ||
| allowedRecipients[_recipient] = _allowed; | ||
| AllowedRecipientChanged(_recipient, _allowed); | ||
| return true; | ||
| } | ||
| - function isRecipientAllowed(address _recipient) internal returns (bool _isAllowed) { | ||
| - if (allowedRecipients[_recipient] | ||
| - || (_recipient == address(extraBalance) | ||
| - // only allowed when at least the amount held in the | ||
| - // extraBalance account has been spent from the DAO | ||
| - && totalRewardToken > extraBalance.accumulatedInput())) | ||
| - return true; | ||
| - else | ||
| - return false; | ||
| - } | ||
| - | ||
| function actualBalance() constant returns (uint _actualBalance) { | ||
| return this.balance - sumOfProposalDeposits; | ||
| } | ||
| function minQuorum(uint _value) internal constant returns (uint _minQuorum) { | ||
| - // minimum of 20% and maximum of 53.33% | ||
| + // minimum of 14.3% and maximum of 47.6% | ||
| return totalSupply / minQuorumDivisor + | ||
| (_value * totalSupply) / (3 * (actualBalance() + rewardToken[address(this)])); | ||
| } | ||
| @@ -910,6 +1023,23 @@ contract DAO is DAOInterface, Token, TokenCreation { | ||
| function unblockMe() returns (bool) { | ||
| return isBlocked(msg.sender); | ||
| } | ||
| + | ||
| + function combinedBalanceOf(address _address){ | ||
| + DAO(parentDAO).balanceOf(_address) + balanceOf(_address); | ||
| + } | ||
| + | ||
| + // approve DAO to transfer your tokens prior to that | ||
| + function swapTokens() { | ||
| + uint balance = DAO(parentDAO).balanceOf(msg.sender); | ||
| + if (DAO(parentDAO).transferFrom(msg.sender, this, balance)) { | ||
| + balances[msg.sender] += balance; | ||
| + totalSupply += balance; | ||
| + if (totalSupply >= minTokensToCreate && !isFueled) { | ||
| + isFueled = true; | ||
| + FuelingToDate(totalSupply); | ||
| + } | ||
| + } | ||
| + } | ||
| } | ||
| contract DAO_Creator { | ||
| @@ -34,15 +34,13 @@ contract TokenCreationInterface { | ||
| uint public minTokensToCreate; | ||
| // True if the DAO reached its minimum fueling goal, false otherwise | ||
| bool public isFueled; | ||
| - // For DAO splits - if privateCreation is 0, then it is a public token | ||
| - // creation, otherwise only the address stored in privateCreation is | ||
| + // For DAO splits - if parentDAO is 0, then it is a public token | ||
| + // creation, otherwise only the address stored in parentDAO is | ||
| // allowed to create tokens | ||
| - address public privateCreation; | ||
| + address public parentDAO; | ||
| // hold extra ether which has been sent after the DAO token | ||
| // creation rate has increased | ||
| ManagedAccount public extraBalance; | ||
| - // tracks the amount of wei given from each contributor (used for refund) | ||
| - mapping (address => uint256) weiGiven; | ||
| /// @dev Constructor setting the minimum fueling goal and the | ||
| /// end of the Token Creation | ||
| @@ -71,10 +69,6 @@ contract TokenCreationInterface { | ||
| /// not reach its minimum fueling goal | ||
| function refund(); | ||
| - /// @return The divisor used to calculate the token creation rate during | ||
| - /// the creation phase | ||
| - function divisor() constant returns (uint divisor); | ||
| - | ||
| event FuelingToDate(uint value); | ||
| event CreatedToken(address indexed to, uint amount); | ||
| event Refund(address indexed to, uint value); | ||
| @@ -85,15 +79,14 @@ contract TokenCreation is TokenCreationInterface, Token { | ||
| function TokenCreation( | ||
| uint _minTokensToCreate, | ||
| uint _closingTime, | ||
| - address _privateCreation, | ||
| + address _parentDAO, | ||
| string _tokenName, | ||
| string _tokenSymbol, | ||
| uint8 _decimalPlaces) { | ||
| closingTime = _closingTime; | ||
| minTokensToCreate = _minTokensToCreate; | ||
| - privateCreation = _privateCreation; | ||
| - extraBalance = new ManagedAccount(address(this), true); | ||
| + parentDAO = _parentDAO; | ||
| name = _tokenName; | ||
| symbol = _tokenSymbol; | ||
| decimals = _decimalPlaces; | ||
| @@ -102,13 +95,11 @@ contract TokenCreation is TokenCreationInterface, Token { | ||
| function createTokenProxy(address _tokenHolder) returns (bool success) { | ||
| if (now < closingTime && msg.value > 0 | ||
| - && (privateCreation == 0 || privateCreation == msg.sender)) { | ||
| + && (parentDAO == 0 || parentDAO == msg.sender)) { | ||
| - uint token = (msg.value * 20) / divisor(); | ||
| - extraBalance.call.value(msg.value - token)(); | ||
| + uint token = msg.value; | ||
| balances[_tokenHolder] += token; | ||
| totalSupply += token; | ||
| - weiGiven[_tokenHolder] += msg.value; | ||
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
|
||
| CreatedToken(_tokenHolder, token); | ||
| if (totalSupply >= minTokensToCreate && !isFueled) { | ||
| isFueled = true; | ||
| @@ -120,33 +111,12 @@ contract TokenCreation is TokenCreationInterface, Token { | ||
| } | ||
| function refund() noEther { | ||
| - if (now > closingTime && !isFueled) { | ||
| - // Get extraBalance - will only succeed when called for the first time | ||
| - if (extraBalance.balance >= extraBalance.accumulatedInput()) | ||
| - extraBalance.payOut(address(this), extraBalance.accumulatedInput()); | ||
| - | ||
| - // Execute refund | ||
| - if (msg.sender.call.value(weiGiven[msg.sender])()) { | ||
| - Refund(msg.sender, weiGiven[msg.sender]); | ||
| + if (now > closingTime && !isFueled && parentDAO == 0) { | ||
| + if (msg.sender.call.value(balances[msg.sender])()) { | ||
| + Refund(msg.sender, balances[msg.sender]); | ||
| totalSupply -= balances[msg.sender]; | ||
| balances[msg.sender] = 0; | ||
| - weiGiven[msg.sender] = 0; | ||
| } | ||
| } | ||
| } | ||
| - | ||
| - function divisor() constant returns (uint divisor) { | ||
| - // The number of (base unit) tokens per wei is calculated | ||
| - // as `msg.value` * 20 / `divisor` | ||
| - // The fueling period starts with a 1:1 ratio | ||
| - if (closingTime - 2 weeks > now) { | ||
| - return 20; | ||
| - // Followed by 10 days with a daily creation rate increase of 5% | ||
| - } else if (closingTime - 4 days > now) { | ||
| - return (20 + (now - (closingTime - 2 weeks)) / (1 days)); | ||
| - // The last 4 days there is a constant creation rate ratio of 1:1.5 | ||
| - } else { | ||
| - return 30; | ||
| - } | ||
| - } | ||
| } | ||
can we make
unVoteinternal? I think its better to minimize the attack surface in this way. Unless you intend for it to be called by DTH.I think it's intended to be used by the DTH too.
So then I think
unVoteshould remove the proposal ID fromvotingRegister[msg.sender]Otherwise if someone votes on too many proposals it will result in them being unable to callunVoteAlldue to block gas limit. Then they cannot callunVoteto remove once blockage at a time sincevotingRegister[msg.sender]remains the same.this is done in
unvoteAll. This can be called at any time to clear things up.