Advertisement
Guest User

Untitled

a guest
May 27th, 2016
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 47.24 KB | None | 0 0
  1. contract ManagedAccountInterface {
  2. // The only address with permission to withdraw from this account
  3. address public owner;
  4. // If true, only the owner of the account can receive ether from it
  5. bool public payOwnerOnly;
  6. // The sum of ether (in wei) which has been sent to this contract
  7. uint public accumulatedInput;
  8.  
  9. /// @notice Sends `_amount` of wei to _recipient
  10. /// @param _amount The amount of wei to send to `_recipient`
  11. /// @param _recipient The address to receive `_amount` of wei
  12. /// @return True if the send completed
  13. function payOut(address _recipient, uint _amount) returns (bool);
  14.  
  15. event PayOut(address indexed _recipient, uint _amount);
  16. }
  17.  
  18.  
  19. contract ManagedAccount is ManagedAccountInterface{
  20.  
  21. // The constructor sets the owner of the account
  22. function ManagedAccount(address _owner, bool _payOwnerOnly) {
  23. owner = _owner;
  24. payOwnerOnly = _payOwnerOnly;
  25. }
  26.  
  27. // When the contract receives a transaction without data this is called.
  28. // It counts the amount of ether it receives and stores it in
  29. // accumulatedInput.
  30. function() {
  31. accumulatedInput += msg.value;
  32. }
  33.  
  34. function payOut(address _recipient, uint _amount) returns (bool) {
  35. if (msg.sender != owner || msg.value > 0 || (payOwnerOnly && _recipient != owner))
  36. throw;
  37. if (_recipient.call.value(_amount)()) {
  38. PayOut(_recipient, _amount);
  39. return true;
  40. } else {
  41. return false;
  42. }
  43. }
  44. }
  45.  
  46. contract TokenInterface {
  47. mapping (address => uint256) balances;
  48. mapping (address => mapping (address => uint256)) allowed;
  49.  
  50. /// Total amount of tokens
  51. uint256 public totalSupply;
  52.  
  53. /// @param _owner The address from which the balance will be retrieved
  54. /// @return The balance
  55. function balanceOf(address _owner) constant returns (uint256 balance);
  56.  
  57. /// @notice Send `_amount` tokens to `_to` from `msg.sender`
  58. /// @param _to The address of the recipient
  59. /// @param _amount The amount of tokens to be transferred
  60. /// @return Whether the transfer was successful or not
  61. function transfer(address _to, uint256 _amount) returns (bool success);
  62.  
  63. /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
  64. /// is approved by `_from`
  65. /// @param _from The address of the origin of the transfer
  66. /// @param _to The address of the recipient
  67. /// @param _amount The amount of tokens to be transferred
  68. /// @return Whether the transfer was successful or not
  69. function transferFrom(address _from, address _to, uint256 _amount) returns (bool success);
  70.  
  71. /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
  72. /// its behalf
  73. /// @param _spender The address of the account able to transfer the tokens
  74. /// @param _amount The amount of tokens to be approved for transfer
  75. /// @return Whether the approval was successful or not
  76. function approve(address _spender, uint256 _amount) returns (bool success);
  77.  
  78. /// @param _owner The address of the account owning tokens
  79. /// @param _spender The address of the account able to transfer the tokens
  80. /// @return Amount of remaining tokens of _owner that _spender is allowed
  81. /// to spend
  82. function allowance(
  83. address _owner,
  84. address _spender
  85. ) constant returns (uint256 remaining);
  86.  
  87. event Transfer(address indexed _from, address indexed _to, uint256 _amount);
  88. event Approval(
  89. address indexed _owner,
  90. address indexed _spender,
  91. uint256 _amount
  92. );
  93. }
  94.  
  95.  
  96. contract Token is TokenInterface {
  97. // Protects users by preventing the execution of method calls that
  98. // inadvertently also transferred ether
  99. modifier noEther() {if (msg.value > 0) throw; _}
  100.  
  101. function balanceOf(address _owner) constant returns (uint256 balance) {
  102. return balances[_owner];
  103. }
  104.  
  105. function transfer(address _to, uint256 _amount) noEther returns (bool success) {
  106. if (balances[msg.sender] >= _amount && _amount > 0) {
  107. balances[msg.sender] -= _amount;
  108. balances[_to] += _amount;
  109. Transfer(msg.sender, _to, _amount);
  110. return true;
  111. } else {
  112. return false;
  113. }
  114. }
  115.  
  116. function transferFrom(
  117. address _from,
  118. address _to,
  119. uint256 _amount
  120. ) noEther returns (bool success) {
  121.  
  122. if (balances[_from] >= _amount
  123. && allowed[_from][msg.sender] >= _amount
  124. && _amount > 0) {
  125.  
  126. balances[_to] += _amount;
  127. balances[_from] -= _amount;
  128. allowed[_from][msg.sender] -= _amount;
  129. Transfer(_from, _to, _amount);
  130. return true;
  131. } else {
  132. return false;
  133. }
  134. }
  135.  
  136. function approve(address _spender, uint256 _amount) returns (bool success) {
  137. allowed[msg.sender][_spender] = _amount;
  138. Approval(msg.sender, _spender, _amount);
  139. return true;
  140. }
  141.  
  142. function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
  143. return allowed[_owner][_spender];
  144. }
  145. }
  146.  
  147. contract TokenCreationInterface {
  148.  
  149. // End of token creation, in Unix time
  150. uint public closingTime;
  151. // Minimum fueling goal of the token creation, denominated in tokens to
  152. // be created
  153. uint public minTokensToCreate;
  154. // True if the DAO reached its minimum fueling goal, false otherwise
  155. bool public isFueled;
  156. // For DAO splits - if privateCreation is 0, then it is a public token
  157. // creation, otherwise only the address stored in privateCreation is
  158. // allowed to create tokens
  159. address public privateCreation;
  160. // hold extra ether which has been sent after the DAO token
  161. // creation rate has increased
  162. ManagedAccount public extraBalance;
  163. // tracks the amount of wei given from each contributor (used for refund)
  164. mapping (address => uint256) weiGiven;
  165.  
  166. /// @dev Constructor setting the minimum fueling goal and the
  167. /// end of the Token Creation
  168. /// @param _minTokensToCreate Minimum fueling goal in number of
  169. /// Tokens to be created
  170. /// @param _closingTime Date (in Unix time) of the end of the Token Creation
  171. /// @param _privateCreation Zero means that the creation is public. A
  172. /// non-zero address represents the only address that can create Tokens
  173. /// (the address can also create Tokens on behalf of other accounts)
  174. // This is the constructor: it can not be overloaded so it is commented out
  175. // function TokenCreation(
  176. // uint _minTokensTocreate,
  177. // uint _closingTime,
  178. // address _privateCreation
  179. // );
  180.  
  181. /// @notice Create Token with `_tokenHolder` as the initial owner of the Token
  182. /// @param _tokenHolder The address of the Tokens's recipient
  183. /// @return Whether the token creation was successful
  184. function createTokenProxy(address _tokenHolder) returns (bool success);
  185.  
  186. /// @notice Refund `msg.sender` in the case the Token Creation did
  187. /// not reach its minimum fueling goal
  188. function refund();
  189.  
  190. /// @return The divisor used to calculate the token creation rate during
  191. /// the creation phase
  192. function divisor() constant returns (uint divisor);
  193.  
  194. event FuelingToDate(uint value);
  195. event CreatedToken(address indexed to, uint amount);
  196. event Refund(address indexed to, uint value);
  197. }
  198.  
  199.  
  200. contract TokenCreation is TokenCreationInterface, Token {
  201. function TokenCreation(
  202. uint _minTokensToCreate,
  203. uint _closingTime,
  204. address _privateCreation) {
  205.  
  206. closingTime = _closingTime;
  207. minTokensToCreate = _minTokensToCreate;
  208. privateCreation = _privateCreation;
  209. extraBalance = new ManagedAccount(address(this), true);
  210. }
  211.  
  212. function createTokenProxy(address _tokenHolder) returns (bool success) {
  213. if (now < closingTime && msg.value > 0
  214. && (privateCreation == 0 || privateCreation == msg.sender)) {
  215.  
  216. uint token = (msg.value * 20) / divisor();
  217. extraBalance.call.value(msg.value - token)();
  218. balances[_tokenHolder] += token;
  219. totalSupply += token;
  220. weiGiven[_tokenHolder] += msg.value;
  221. CreatedToken(_tokenHolder, token);
  222. if (totalSupply >= minTokensToCreate && !isFueled) {
  223. isFueled = true;
  224. FuelingToDate(totalSupply);
  225. }
  226. return true;
  227. }
  228. throw;
  229. }
  230.  
  231. function refund() noEther {
  232. if (now > closingTime && !isFueled) {
  233. // Get extraBalance - will only succeed when called for the first time
  234. if (extraBalance.balance >= extraBalance.accumulatedInput())
  235. extraBalance.payOut(address(this), extraBalance.accumulatedInput());
  236.  
  237. // Execute refund
  238. if (msg.sender.call.value(weiGiven[msg.sender])()) {
  239. Refund(msg.sender, weiGiven[msg.sender]);
  240. totalSupply -= balances[msg.sender];
  241. balances[msg.sender] = 0;
  242. weiGiven[msg.sender] = 0;
  243. }
  244. }
  245. }
  246.  
  247. function divisor() constant returns (uint divisor) {
  248. // The number of (base unit) tokens per wei is calculated
  249. // as `msg.value` * 20 / `divisor`
  250. // The fueling period starts with a 1:1 ratio
  251. if (closingTime - 2 weeks > now) {
  252. return 20;
  253. // Followed by 10 days with a daily creation rate increase of 5%
  254. } else if (closingTime - 4 days > now) {
  255. return (20 + (now - (closingTime - 2 weeks)) / (1 days));
  256. // The last 4 days there is a constant creation rate ratio of 1:1.5
  257. } else {
  258. return 30;
  259. }
  260. }
  261. }
  262.  
  263. contract DAOInterface {
  264.  
  265. // The amount of days for which people who try to participate in the
  266. // creation by calling the fallback function will still get their ether back
  267. uint constant creationGracePeriod = 40 days;
  268. // The minimum debate period that a generic proposal can have
  269. uint constant minProposalDebatePeriod = 2 weeks;
  270. // The minimum debate period that a split proposal can have
  271. uint constant minSplitDebatePeriod = 1 weeks;
  272. // Period of days inside which it's possible to execute a DAO split
  273. uint constant splitExecutionPeriod = 27 days;
  274. // Period of time after which the minimum Quorum is halved
  275. uint constant quorumHalvingPeriod = 25 weeks;
  276. // Period after which a proposal is closed
  277. // (used in the case `executeProposal` fails because it throws)
  278. uint constant executeProposalPeriod = 10 days;
  279. // Denotes the maximum proposal deposit that can be given. It is given as
  280. // a fraction of total Ether spent plus balance of the DAO
  281. uint constant maxDepositDivisor = 100;
  282.  
  283. // Proposals to spend the DAO's ether or to choose a new Curator
  284. Proposal[] public proposals;
  285. // The quorum needed for each proposal is partially calculated by
  286. // totalSupply / minQuorumDivisor
  287. uint public minQuorumDivisor;
  288. // The unix time of the last time quorum was reached on a proposal
  289. uint public lastTimeMinQuorumMet;
  290.  
  291. // Address of the curator
  292. address public curator;
  293. // The whitelist: List of addresses the DAO is allowed to send ether to
  294. mapping (address => bool) public allowedRecipients;
  295.  
  296. // Tracks the addresses that own Reward Tokens. Those addresses can only be
  297. // DAOs that have split from the original DAO. Conceptually, Reward Tokens
  298. // represent the proportion of the rewards that the DAO has the right to
  299. // receive. These Reward Tokens are generated when the DAO spends ether.
  300. mapping (address => uint) public rewardToken;
  301. // Total supply of rewardToken
  302. uint public totalRewardToken;
  303.  
  304. // The account used to manage the rewards which are to be distributed to the
  305. // DAO Token Holders of this DAO
  306. ManagedAccount public rewardAccount;
  307.  
  308. // The account used to manage the rewards which are to be distributed to
  309. // any DAO that holds Reward Tokens
  310. ManagedAccount public DAOrewardAccount;
  311.  
  312. // Amount of rewards (in wei) already paid out to a certain DAO
  313. mapping (address => uint) public DAOpaidOut;
  314.  
  315. // Amount of rewards (in wei) already paid out to a certain address
  316. mapping (address => uint) public paidOut;
  317. // Map of addresses blocked during a vote (not allowed to transfer DAO
  318. // tokens). The address points to the proposal ID.
  319. mapping (address => uint) public blocked;
  320.  
  321. // The minimum deposit (in wei) required to submit any proposal that is not
  322. // requesting a new Curator (no deposit is required for splits)
  323. uint public proposalDeposit;
  324.  
  325. // the accumulated sum of all current proposal deposits
  326. uint sumOfProposalDeposits;
  327.  
  328. // Contract that is able to create a new DAO (with the same code as
  329. // this one), used for splits
  330. DAO_Creator public daoCreator;
  331.  
  332. // A proposal with `newCurator == false` represents a transaction
  333. // to be issued by this DAO
  334. // A proposal with `newCurator == true` represents a DAO split
  335. struct Proposal {
  336. // The address where the `amount` will go to if the proposal is accepted
  337. // or if `newCurator` is true, the proposed Curator of
  338. // the new DAO).
  339. address recipient;
  340. // The amount to transfer to `recipient` if the proposal is accepted.
  341. uint amount;
  342. // A plain text description of the proposal
  343. string description;
  344. // A unix timestamp, denoting the end of the voting period
  345. uint votingDeadline;
  346. // True if the proposal's votes have yet to be counted, otherwise False
  347. bool open;
  348. // True if quorum has been reached, the votes have been counted, and
  349. // the majority said yes
  350. bool proposalPassed;
  351. // A hash to check validity of a proposal
  352. bytes32 proposalHash;
  353. // Deposit in wei the creator added when submitting their proposal. It
  354. // is taken from the msg.value of a newProposal call.
  355. uint proposalDeposit;
  356. // True if this proposal is to assign a new Curator
  357. bool newCurator;
  358. // Data needed for splitting the DAO
  359. SplitData[] splitData;
  360. // Number of Tokens in favor of the proposal
  361. uint yea;
  362. // Number of Tokens opposed to the proposal
  363. uint nay;
  364. // Simple mapping to check if a shareholder has voted for it
  365. mapping (address => bool) votedYes;
  366. // Simple mapping to check if a shareholder has voted against it
  367. mapping (address => bool) votedNo;
  368. // Address of the shareholder who created the proposal
  369. address creator;
  370. }
  371.  
  372. // Used only in the case of a newCurator proposal.
  373. struct SplitData {
  374. // The balance of the current DAO minus the deposit at the time of split
  375. uint splitBalance;
  376. // The total amount of DAO Tokens in existence at the time of split.
  377. uint totalSupply;
  378. // Amount of Reward Tokens owned by the DAO at the time of split.
  379. uint rewardToken;
  380. // The new DAO contract created at the time of split.
  381. DAO newDAO;
  382. }
  383.  
  384. // Used to restrict access to certain functions to only DAO Token Holders
  385. modifier onlyTokenholders {}
  386.  
  387. /// @dev Constructor setting the Curator and the address
  388. /// for the contract able to create another DAO as well as the parameters
  389. /// for the DAO Token Creation
  390. /// @param _curator The Curator
  391. /// @param _daoCreator The contract able to (re)create this DAO
  392. /// @param _proposalDeposit The deposit to be paid for a regular proposal
  393. /// @param _minTokensToCreate Minimum required wei-equivalent tokens
  394. /// to be created for a successful DAO Token Creation
  395. /// @param _closingTime Date (in Unix time) of the end of the DAO Token Creation
  396. /// @param _privateCreation If zero the DAO Token Creation is open to public, a
  397. /// non-zero address means that the DAO Token Creation is only for the address
  398. // This is the constructor: it can not be overloaded so it is commented out
  399. // function DAO(
  400. // address _curator,
  401. // DAO_Creator _daoCreator,
  402. // uint _proposalDeposit,
  403. // uint _minTokensToCreate,
  404. // uint _closingTime,
  405. // address _privateCreation
  406. // );
  407.  
  408. /// @notice Create Token with `msg.sender` as the beneficiary
  409. /// @return Whether the token creation was successful
  410. function () returns (bool success);
  411.  
  412.  
  413. /// @dev This function is used to send ether back
  414. /// to the DAO, it can also be used to receive payments that should not be
  415. /// counted as rewards (donations, grants, etc.)
  416. /// @return Whether the DAO received the ether successfully
  417. function receiveEther() returns(bool);
  418.  
  419. /// @notice `msg.sender` creates a proposal to send `_amount` Wei to
  420. /// `_recipient` with the transaction data `_transactionData`. If
  421. /// `_newCurator` is true, then this is a proposal that splits the
  422. /// DAO and sets `_recipient` as the new DAO's Curator.
  423. /// @param _recipient Address of the recipient of the proposed transaction
  424. /// @param _amount Amount of wei to be sent with the proposed transaction
  425. /// @param _description String describing the proposal
  426. /// @param _transactionData Data of the proposed transaction
  427. /// @param _debatingPeriod Time used for debating a proposal, at least 2
  428. /// weeks for a regular proposal, 10 days for new Curator proposal
  429. /// @param _newCurator Bool defining whether this proposal is about
  430. /// a new Curator or not
  431. /// @return The proposal ID. Needed for voting on the proposal
  432. function newProposal(
  433. address _recipient,
  434. uint _amount,
  435. string _description,
  436. bytes _transactionData,
  437. uint _debatingPeriod,
  438. bool _newCurator
  439. ) onlyTokenholders returns (uint _proposalID);
  440.  
  441. /// @notice Check that the proposal with the ID `_proposalID` matches the
  442. /// transaction which sends `_amount` with data `_transactionData`
  443. /// to `_recipient`
  444. /// @param _proposalID The proposal ID
  445. /// @param _recipient The recipient of the proposed transaction
  446. /// @param _amount The amount of wei to be sent in the proposed transaction
  447. /// @param _transactionData The data of the proposed transaction
  448. /// @return Whether the proposal ID matches the transaction data or not
  449. function checkProposalCode(
  450. uint _proposalID,
  451. address _recipient,
  452. uint _amount,
  453. bytes _transactionData
  454. ) constant returns (bool _codeChecksOut);
  455.  
  456. /// @notice Vote on proposal `_proposalID` with `_supportsProposal`
  457. /// @param _proposalID The proposal ID
  458. /// @param _supportsProposal Yes/No - support of the proposal
  459. /// @return The vote ID.
  460. function vote(
  461. uint _proposalID,
  462. bool _supportsProposal
  463. ) onlyTokenholders returns (uint _voteID);
  464.  
  465. /// @notice Checks whether proposal `_proposalID` with transaction data
  466. /// `_transactionData` has been voted for or rejected, and executes the
  467. /// transaction in the case it has been voted for.
  468. /// @param _proposalID The proposal ID
  469. /// @param _transactionData The data of the proposed transaction
  470. /// @return Whether the proposed transaction has been executed or not
  471. function executeProposal(
  472. uint _proposalID,
  473. bytes _transactionData
  474. ) returns (bool _success);
  475.  
  476. /// @notice ATTENTION! I confirm to move my remaining ether to a new DAO
  477. /// with `_newCurator` as the new Curator, as has been
  478. /// proposed in proposal `_proposalID`. This will burn my tokens. This can
  479. /// not be undone and will split the DAO into two DAO's, with two
  480. /// different underlying tokens.
  481. /// @param _proposalID The proposal ID
  482. /// @param _newCurator The new Curator of the new DAO
  483. /// @dev This function, when called for the first time for this proposal,
  484. /// will create a new DAO and send the sender's portion of the remaining
  485. /// ether and Reward Tokens to the new DAO. It will also burn the DAO Tokens
  486. /// of the sender.
  487. function splitDAO(
  488. uint _proposalID,
  489. address _newCurator
  490. ) returns (bool _success);
  491.  
  492. /// @dev can only be called by the DAO itself through a proposal
  493. /// updates the contract of the DAO by sending all ether and rewardTokens
  494. /// to the new DAO. The new DAO needs to be approved by the Curator
  495. /// @param _newContract the address of the new contract
  496. function newContract(address _newContract);
  497.  
  498.  
  499. /// @notice Add a new possible recipient `_recipient` to the whitelist so
  500. /// that the DAO can send transactions to them (using proposals)
  501. /// @param _recipient New recipient address
  502. /// @dev Can only be called by the current Curator
  503. /// @return Whether successful or not
  504. function changeAllowedRecipients(address _recipient, bool _allowed) external returns (bool _success);
  505.  
  506.  
  507. /// @notice Change the minimum deposit required to submit a proposal
  508. /// @param _proposalDeposit The new proposal deposit
  509. /// @dev Can only be called by this DAO (through proposals with the
  510. /// recipient being this DAO itself)
  511. function changeProposalDeposit(uint _proposalDeposit) external;
  512.  
  513. /// @notice Move rewards from the DAORewards managed account
  514. /// @param _toMembers If true rewards are moved to the actual reward account
  515. /// for the DAO. If not then it's moved to the DAO itself
  516. /// @return Whether the call was successful
  517. function retrieveDAOReward(bool _toMembers) external returns (bool _success);
  518.  
  519. /// @notice Get my portion of the reward that was sent to `rewardAccount`
  520. /// @return Whether the call was successful
  521. function getMyReward() returns(bool _success);
  522.  
  523. /// @notice Withdraw `_account`'s portion of the reward from `rewardAccount`
  524. /// to `_account`'s balance
  525. /// @return Whether the call was successful
  526. function withdrawRewardFor(address _account) internal returns (bool _success);
  527.  
  528. /// @notice Send `_amount` tokens to `_to` from `msg.sender`. Prior to this
  529. /// getMyReward() is called.
  530. /// @param _to The address of the recipient
  531. /// @param _amount The amount of tokens to be transfered
  532. /// @return Whether the transfer was successful or not
  533. function transferWithoutReward(address _to, uint256 _amount) returns (bool success);
  534.  
  535. /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
  536. /// is approved by `_from`. Prior to this getMyReward() is called.
  537. /// @param _from The address of the sender
  538. /// @param _to The address of the recipient
  539. /// @param _amount The amount of tokens to be transfered
  540. /// @return Whether the transfer was successful or not
  541. function transferFromWithoutReward(
  542. address _from,
  543. address _to,
  544. uint256 _amount
  545. ) returns (bool success);
  546.  
  547. /// @notice Doubles the 'minQuorumDivisor' in the case quorum has not been
  548. /// achieved in 52 weeks
  549. /// @return Whether the change was successful or not
  550. function halveMinQuorum() returns (bool _success);
  551.  
  552. /// @return total number of proposals ever created
  553. function numberOfProposals() constant returns (uint _numberOfProposals);
  554.  
  555. /// @param _proposalID Id of the new curator proposal
  556. /// @return Address of the new DAO
  557. function getNewDAOAddress(uint _proposalID) constant returns (address _newDAO);
  558.  
  559. /// @param _account The address of the account which is checked.
  560. /// @return Whether the account is blocked (not allowed to transfer tokens) or not.
  561. function isBlocked(address _account) internal returns (bool);
  562.  
  563. /// @notice If the caller is blocked by a proposal whose voting deadline
  564. /// has exprired then unblock him.
  565. /// @return Whether the account is blocked (not allowed to transfer tokens) or not.
  566. function unblockMe() returns (bool);
  567.  
  568. event ProposalAdded(
  569. uint indexed proposalID,
  570. address recipient,
  571. uint amount,
  572. bool newCurator,
  573. string description
  574. );
  575. event Voted(uint indexed proposalID, bool position, address indexed voter);
  576. event ProposalTallied(uint indexed proposalID, bool result, uint quorum);
  577. event NewCurator(address indexed _newCurator);
  578. event AllowedRecipientChanged(address indexed _recipient, bool _allowed);
  579. }
  580.  
  581. // The DAO contract itself
  582. contract DAO is DAOInterface, Token, TokenCreation {
  583.  
  584. // Modifier that allows only shareholders to vote and create new proposals
  585. modifier onlyTokenholders {
  586. if (balanceOf(msg.sender) == 0) throw;
  587. _
  588. }
  589.  
  590. function DAO(
  591. address _curator,
  592. DAO_Creator _daoCreator,
  593. uint _proposalDeposit,
  594. uint _minTokensToCreate,
  595. uint _closingTime,
  596. address _privateCreation
  597. ) TokenCreation(_minTokensToCreate, _closingTime, _privateCreation) {
  598.  
  599. curator = _curator;
  600. daoCreator = _daoCreator;
  601. proposalDeposit = _proposalDeposit;
  602. rewardAccount = new ManagedAccount(address(this), false);
  603. DAOrewardAccount = new ManagedAccount(address(this), false);
  604. if (address(rewardAccount) == 0)
  605. throw;
  606. if (address(DAOrewardAccount) == 0)
  607. throw;
  608. lastTimeMinQuorumMet = now;
  609. minQuorumDivisor = 5; // sets the minimal quorum to 20%
  610. proposals.length = 1; // avoids a proposal with ID 0 because it is used
  611.  
  612. allowedRecipients[address(this)] = true;
  613. allowedRecipients[curator] = true;
  614. }
  615.  
  616. function () returns (bool success) {
  617. if (now < closingTime + creationGracePeriod && msg.sender != address(extraBalance))
  618. return createTokenProxy(msg.sender);
  619. else
  620. return receiveEther();
  621. }
  622.  
  623.  
  624. function receiveEther() returns (bool) {
  625. return true;
  626. }
  627.  
  628.  
  629. function newProposal(
  630. address _recipient,
  631. uint _amount,
  632. string _description,
  633. bytes _transactionData,
  634. uint _debatingPeriod,
  635. bool _newCurator
  636. ) onlyTokenholders returns (uint _proposalID) {
  637.  
  638. // Sanity check
  639. if (_newCurator && (
  640. _amount != 0
  641. || _transactionData.length != 0
  642. || _recipient == curator
  643. || msg.value > 0
  644. || _debatingPeriod < minSplitDebatePeriod)) {
  645. throw;
  646. } else if (
  647. !_newCurator
  648. && (!isRecipientAllowed(_recipient) || (_debatingPeriod < minProposalDebatePeriod))
  649. ) {
  650. throw;
  651. }
  652.  
  653. if (_debatingPeriod > 8 weeks)
  654. throw;
  655.  
  656. if (!isFueled
  657. || now < closingTime
  658. || (msg.value < proposalDeposit && !_newCurator)) {
  659.  
  660. throw;
  661. }
  662.  
  663. if (now + _debatingPeriod < now) // prevents overflow
  664. throw;
  665.  
  666. // to prevent a 51% attacker to convert the ether into deposit
  667. if (msg.sender == address(this))
  668. throw;
  669.  
  670. _proposalID = proposals.length++;
  671. Proposal p = proposals[_proposalID];
  672. p.recipient = _recipient;
  673. p.amount = _amount;
  674. p.description = _description;
  675. p.proposalHash = sha3(_recipient, _amount, _transactionData);
  676. p.votingDeadline = now + _debatingPeriod;
  677. p.open = true;
  678. //p.proposalPassed = False; // that's default
  679. p.newCurator = _newCurator;
  680. if (_newCurator)
  681. p.splitData.length++;
  682. p.creator = msg.sender;
  683. p.proposalDeposit = msg.value;
  684.  
  685. sumOfProposalDeposits += msg.value;
  686.  
  687. ProposalAdded(
  688. _proposalID,
  689. _recipient,
  690. _amount,
  691. _newCurator,
  692. _description
  693. );
  694. }
  695.  
  696.  
  697. function checkProposalCode(
  698. uint _proposalID,
  699. address _recipient,
  700. uint _amount,
  701. bytes _transactionData
  702. ) noEther constant returns (bool _codeChecksOut) {
  703. Proposal p = proposals[_proposalID];
  704. return p.proposalHash == sha3(_recipient, _amount, _transactionData);
  705. }
  706.  
  707.  
  708. function vote(
  709. uint _proposalID,
  710. bool _supportsProposal
  711. ) onlyTokenholders noEther returns (uint _voteID) {
  712.  
  713. Proposal p = proposals[_proposalID];
  714. if (p.votedYes[msg.sender]
  715. || p.votedNo[msg.sender]
  716. || now >= p.votingDeadline) {
  717.  
  718. throw;
  719. }
  720.  
  721. if (_supportsProposal) {
  722. p.yea += balances[msg.sender];
  723. p.votedYes[msg.sender] = true;
  724. } else {
  725. p.nay += balances[msg.sender];
  726. p.votedNo[msg.sender] = true;
  727. }
  728.  
  729. if (blocked[msg.sender] == 0) {
  730. blocked[msg.sender] = _proposalID;
  731. } else if (p.votingDeadline > proposals[blocked[msg.sender]].votingDeadline) {
  732. // this proposal's voting deadline is further into the future than
  733. // the proposal that blocks the sender so make it the blocker
  734. blocked[msg.sender] = _proposalID;
  735. }
  736.  
  737. Voted(_proposalID, _supportsProposal, msg.sender);
  738. }
  739.  
  740.  
  741. function executeProposal(
  742. uint _proposalID,
  743. bytes _transactionData
  744. ) noEther returns (bool _success) {
  745.  
  746. Proposal p = proposals[_proposalID];
  747.  
  748. uint waitPeriod = p.newCurator
  749. ? splitExecutionPeriod
  750. : executeProposalPeriod;
  751. // If we are over deadline and waiting period, assert proposal is closed
  752. if (p.open && now > p.votingDeadline + waitPeriod) {
  753. closeProposal(_proposalID);
  754. return;
  755. }
  756.  
  757. // Check if the proposal can be executed
  758. if (now < p.votingDeadline // has the voting deadline arrived?
  759. // Have the votes been counted?
  760. || !p.open
  761. // Does the transaction code match the proposal?
  762. || p.proposalHash != sha3(p.recipient, p.amount, _transactionData)) {
  763.  
  764. throw;
  765. }
  766.  
  767. // If the curator removed the recipient from the whitelist, close the proposal
  768. // in order to free the deposit and allow unblocking of voters
  769. if (!isRecipientAllowed(p.recipient)) {
  770. closeProposal(_proposalID);
  771. p.creator.send(p.proposalDeposit);
  772. return;
  773. }
  774.  
  775. bool proposalCheck = true;
  776.  
  777. if (p.amount > actualBalance())
  778. proposalCheck = false;
  779.  
  780. uint quorum = p.yea + p.nay;
  781.  
  782. // require 53% for calling newContract()
  783. if (_transactionData.length >= 4 && _transactionData[0] == 0x68
  784. && _transactionData[1] == 0x37 && _transactionData[2] == 0xff
  785. && _transactionData[3] == 0x1e
  786. && quorum < minQuorum(actualBalance() + rewardToken[address(this)])) {
  787.  
  788. proposalCheck = false;
  789. }
  790.  
  791. if (quorum >= minQuorum(p.amount)) {
  792. if (!p.creator.send(p.proposalDeposit))
  793. throw;
  794.  
  795. lastTimeMinQuorumMet = now;
  796. // set the minQuorum to 20% again, in the case it has been reached
  797. if (quorum > totalSupply / 5)
  798. minQuorumDivisor = 5;
  799. }
  800.  
  801. // Execute result
  802. if (quorum >= minQuorum(p.amount) && p.yea > p.nay && proposalCheck) {
  803. if (!p.recipient.call.value(p.amount)(_transactionData))
  804. throw;
  805.  
  806. p.proposalPassed = true;
  807. _success = true;
  808.  
  809. // only create reward tokens when ether is not sent to the DAO itself and
  810. // related addresses. Proxy addresses should be forbidden by the curator.
  811. if (p.recipient != address(this) && p.recipient != address(rewardAccount)
  812. && p.recipient != address(DAOrewardAccount)
  813. && p.recipient != address(extraBalance)
  814. && p.recipient != address(curator)) {
  815.  
  816. rewardToken[address(this)] += p.amount;
  817. totalRewardToken += p.amount;
  818. }
  819. }
  820.  
  821. closeProposal(_proposalID);
  822.  
  823. // Initiate event
  824. ProposalTallied(_proposalID, _success, quorum);
  825. }
  826.  
  827.  
  828. function closeProposal(uint _proposalID) internal {
  829. Proposal p = proposals[_proposalID];
  830. if (p.open)
  831. sumOfProposalDeposits -= p.proposalDeposit;
  832. p.open = false;
  833. }
  834.  
  835. function splitDAO(
  836. uint _proposalID,
  837. address _newCurator
  838. ) noEther onlyTokenholders returns (bool _success) {
  839.  
  840. Proposal p = proposals[_proposalID];
  841.  
  842. // Sanity check
  843.  
  844. if (now < p.votingDeadline // has the voting deadline arrived?
  845. //The request for a split expires XX days after the voting deadline
  846. || now > p.votingDeadline + splitExecutionPeriod
  847. // Does the new Curator address match?
  848. || p.recipient != _newCurator
  849. // Is it a new curator proposal?
  850. || !p.newCurator
  851. // Have you voted for this split?
  852. || !p.votedYes[msg.sender]
  853. // Did you already vote on another proposal?
  854. || (blocked[msg.sender] != _proposalID && blocked[msg.sender] != 0) ) {
  855.  
  856. throw;
  857. }
  858.  
  859. // If the new DAO doesn't exist yet, create the new DAO and store the
  860. // current split data
  861. if (address(p.splitData[0].newDAO) == 0) {
  862. p.splitData[0].newDAO = createNewDAO(_newCurator);
  863. // Call depth limit reached, etc.
  864. if (address(p.splitData[0].newDAO) == 0)
  865. throw;
  866. // should never happen
  867. if (this.balance < sumOfProposalDeposits)
  868. throw;
  869. p.splitData[0].splitBalance = actualBalance();
  870. p.splitData[0].rewardToken = rewardToken[address(this)];
  871. p.splitData[0].totalSupply = totalSupply;
  872. p.proposalPassed = true;
  873. }
  874.  
  875. // Move ether and assign new Tokens
  876. uint fundsToBeMoved =
  877. (balances[msg.sender] * p.splitData[0].splitBalance) /
  878. p.splitData[0].totalSupply;
  879. if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false)
  880. throw;
  881.  
  882.  
  883. // Assign reward rights to new DAO
  884. uint rewardTokenToBeMoved =
  885. (balances[msg.sender] * p.splitData[0].rewardToken) /
  886. p.splitData[0].totalSupply;
  887.  
  888. uint paidOutToBeMoved = DAOpaidOut[address(this)] * rewardTokenToBeMoved /
  889. rewardToken[address(this)];
  890.  
  891. rewardToken[address(p.splitData[0].newDAO)] += rewardTokenToBeMoved;
  892. if (rewardToken[address(this)] < rewardTokenToBeMoved)
  893. throw;
  894. rewardToken[address(this)] -= rewardTokenToBeMoved;
  895.  
  896. DAOpaidOut[address(p.splitData[0].newDAO)] += paidOutToBeMoved;
  897. if (DAOpaidOut[address(this)] < paidOutToBeMoved)
  898. throw;
  899. DAOpaidOut[address(this)] -= paidOutToBeMoved;
  900.  
  901. // Burn DAO Tokens
  902. Transfer(msg.sender, 0, balances[msg.sender]);
  903. withdrawRewardFor(msg.sender); // be nice, and get his rewards
  904. totalSupply -= balances[msg.sender];
  905. balances[msg.sender] = 0;
  906. paidOut[msg.sender] = 0;
  907. return true;
  908. }
  909.  
  910. function newContract(address _newContract){
  911. if (msg.sender != address(this) || !allowedRecipients[_newContract]) return;
  912. // move all ether
  913. if (!_newContract.call.value(address(this).balance)()) {
  914. throw;
  915. }
  916.  
  917. //move all reward tokens
  918. rewardToken[_newContract] += rewardToken[address(this)];
  919. rewardToken[address(this)] = 0;
  920. DAOpaidOut[_newContract] += DAOpaidOut[address(this)];
  921. DAOpaidOut[address(this)] = 0;
  922. }
  923.  
  924.  
  925. function retrieveDAOReward(bool _toMembers) external noEther returns (bool _success) {
  926. DAO dao = DAO(msg.sender);
  927.  
  928. if ((rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /
  929. totalRewardToken < DAOpaidOut[msg.sender])
  930. throw;
  931.  
  932. uint reward =
  933. (rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /
  934. totalRewardToken - DAOpaidOut[msg.sender];
  935. if(_toMembers) {
  936. if (!DAOrewardAccount.payOut(dao.rewardAccount(), reward))
  937. throw;
  938. }
  939. else {
  940. if (!DAOrewardAccount.payOut(dao, reward))
  941. throw;
  942. }
  943. DAOpaidOut[msg.sender] += reward;
  944. return true;
  945. }
  946.  
  947. function getMyReward() noEther returns (bool _success) {
  948. return withdrawRewardFor(msg.sender);
  949. }
  950.  
  951.  
  952. function withdrawRewardFor(address _account) noEther internal returns (bool _success) {
  953. if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply < paidOut[_account])
  954. throw;
  955.  
  956. uint reward =
  957. (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];
  958. if (!rewardAccount.payOut(_account, reward))
  959. throw;
  960. paidOut[_account] += reward;
  961. return true;
  962. }
  963.  
  964.  
  965. function transfer(address _to, uint256 _value) returns (bool success) {
  966. if (isFueled
  967. && now > closingTime
  968. && !isBlocked(msg.sender)
  969. && transferPaidOut(msg.sender, _to, _value)
  970. && super.transfer(_to, _value)) {
  971.  
  972. return true;
  973. } else {
  974. throw;
  975. }
  976. }
  977.  
  978.  
  979. function transferWithoutReward(address _to, uint256 _value) returns (bool success) {
  980. if (!getMyReward())
  981. throw;
  982. return transfer(_to, _value);
  983. }
  984.  
  985.  
  986. function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
  987. if (isFueled
  988. && now > closingTime
  989. && !isBlocked(_from)
  990. && transferPaidOut(_from, _to, _value)
  991. && super.transferFrom(_from, _to, _value)) {
  992.  
  993. return true;
  994. } else {
  995. throw;
  996. }
  997. }
  998.  
  999.  
  1000. function transferFromWithoutReward(
  1001. address _from,
  1002. address _to,
  1003. uint256 _value
  1004. ) returns (bool success) {
  1005.  
  1006. if (!withdrawRewardFor(_from))
  1007. throw;
  1008. return transferFrom(_from, _to, _value);
  1009. }
  1010.  
  1011.  
  1012. function transferPaidOut(
  1013. address _from,
  1014. address _to,
  1015. uint256 _value
  1016. ) internal returns (bool success) {
  1017.  
  1018. uint transferPaidOut = paidOut[_from] * _value / balanceOf(_from);
  1019. if (transferPaidOut > paidOut[_from])
  1020. throw;
  1021. paidOut[_from] -= transferPaidOut;
  1022. paidOut[_to] += transferPaidOut;
  1023. return true;
  1024. }
  1025.  
  1026.  
  1027. function changeProposalDeposit(uint _proposalDeposit) noEther external {
  1028. if (msg.sender != address(this) || _proposalDeposit > (actualBalance() + rewardToken[address(this)])
  1029. / maxDepositDivisor) {
  1030.  
  1031. throw;
  1032. }
  1033. proposalDeposit = _proposalDeposit;
  1034. }
  1035.  
  1036.  
  1037. function changeAllowedRecipients(address _recipient, bool _allowed) noEther external returns (bool _success) {
  1038. if (msg.sender != curator)
  1039. throw;
  1040. allowedRecipients[_recipient] = _allowed;
  1041. AllowedRecipientChanged(_recipient, _allowed);
  1042. return true;
  1043. }
  1044.  
  1045.  
  1046. function isRecipientAllowed(address _recipient) internal returns (bool _isAllowed) {
  1047. if (allowedRecipients[_recipient]
  1048. || (_recipient == address(extraBalance)
  1049. // only allowed when at least the amount held in the
  1050. // extraBalance account has been spent from the DAO
  1051. && totalRewardToken > extraBalance.accumulatedInput()))
  1052. return true;
  1053. else
  1054. return false;
  1055. }
  1056.  
  1057. function actualBalance() constant returns (uint _actualBalance) {
  1058. return this.balance - sumOfProposalDeposits;
  1059. }
  1060.  
  1061.  
  1062. function minQuorum(uint _value) internal constant returns (uint _minQuorum) {
  1063. // minimum of 20% and maximum of 53.33%
  1064. return totalSupply / minQuorumDivisor +
  1065. (_value * totalSupply) / (3 * (actualBalance() + rewardToken[address(this)]));
  1066. }
  1067.  
  1068.  
  1069. function halveMinQuorum() returns (bool _success) {
  1070. // this can only be called after `quorumHalvingPeriod` has passed or at anytime
  1071. // by the curator with a delay of at least `minProposalDebatePeriod` between the calls
  1072. if ((lastTimeMinQuorumMet < (now - quorumHalvingPeriod) || msg.sender == curator)
  1073. && lastTimeMinQuorumMet < (now - minProposalDebatePeriod)) {
  1074. lastTimeMinQuorumMet = now;
  1075. minQuorumDivisor *= 2;
  1076. return true;
  1077. } else {
  1078. return false;
  1079. }
  1080. }
  1081.  
  1082. function createNewDAO(address _newCurator) internal returns (DAO _newDAO) {
  1083. NewCurator(_newCurator);
  1084. return daoCreator.createDAO(_newCurator, 0, 0, now + splitExecutionPeriod);
  1085. }
  1086.  
  1087. function numberOfProposals() constant returns (uint _numberOfProposals) {
  1088. // Don't count index 0. It's used by isBlocked() and exists from start
  1089. return proposals.length - 1;
  1090. }
  1091.  
  1092. function getNewDAOAddress(uint _proposalID) constant returns (address _newDAO) {
  1093. return proposals[_proposalID].splitData[0].newDAO;
  1094. }
  1095.  
  1096. function isBlocked(address _account) internal returns (bool) {
  1097. if (blocked[_account] == 0)
  1098. return false;
  1099. Proposal p = proposals[blocked[_account]];
  1100. if (now > p.votingDeadline) {
  1101. blocked[_account] = 0;
  1102. return false;
  1103. } else {
  1104. return true;
  1105. }
  1106. }
  1107.  
  1108. function unblockMe() returns (bool) {
  1109. return isBlocked(msg.sender);
  1110. }
  1111. }
  1112.  
  1113. contract DAO_Creator {
  1114. function createDAO(
  1115. address _curator,
  1116. uint _proposalDeposit,
  1117. uint _minTokensToCreate,
  1118. uint _closingTime
  1119. ) returns (DAO _newDAO) {
  1120.  
  1121. return new DAO(
  1122. _curator,
  1123. DAO_Creator(this),
  1124. _proposalDeposit,
  1125. _minTokensToCreate,
  1126. _closingTime,
  1127. msg.sender
  1128. );
  1129. }
  1130. }
  1131.  
  1132. contract DAOSecurity {
  1133.  
  1134. // The total cost of the Offer. Exactly this amount is transfered from the
  1135. // Client to the Offer contract when the Offer is signed by the Client.
  1136. // Set once by the Offerer.
  1137. uint totalCosts;
  1138.  
  1139. // Initial withdraw to the Contractor. It is done the moment the Offer is
  1140. // signed.
  1141. // Set once by the Offerer.
  1142. uint oneTimeCosts;
  1143.  
  1144. // The minimal daily withdraw limit that the Contractor accepts.
  1145. // Set once by the Offerer.
  1146. uint128 minDailyWithdrawLimit;
  1147.  
  1148. // The amount of wei the Contractor has right to withdraw daily above the
  1149. // initial withdraw. The Contractor does not have to do the withdraws every
  1150. // day as this amount accumulates.
  1151. uint128 dailyWithdrawLimit;
  1152.  
  1153. // The address of the Contractor.
  1154. address contractor;
  1155.  
  1156. // The hash of the Proposal/Offer document.
  1157. bytes32 hashOfTheProposalDocument;
  1158.  
  1159. // The time of the last withdraw to the Contractor.
  1160. uint lastPayment;
  1161.  
  1162. uint dateOfSignature;
  1163. DAO client; // address of DAO
  1164. DAO originalClient; // address of DAO who signed the contract
  1165. bool isContractValid;
  1166.  
  1167. modifier onlyClient {
  1168. if (msg.sender != address(client))
  1169. throw;
  1170. _
  1171. }
  1172.  
  1173. // Prevents methods from perfoming any value transfer
  1174. modifier noEther() {if (msg.value > 0) throw; _}
  1175.  
  1176. function DAOSecurity(
  1177. address _contractor,
  1178. address _client,
  1179. bytes32 _hashOfTheProposalDocument,
  1180. uint _totalCosts,
  1181. uint _oneTimeCosts,
  1182. uint128 _minDailyWithdrawLimit
  1183. ) {
  1184. contractor = _contractor;
  1185. originalClient = DAO(_client);
  1186. client = DAO(_client);
  1187. hashOfTheProposalDocument = _hashOfTheProposalDocument;
  1188. totalCosts = _totalCosts;
  1189. oneTimeCosts = _oneTimeCosts;
  1190. minDailyWithdrawLimit = _minDailyWithdrawLimit;
  1191. dailyWithdrawLimit = _minDailyWithdrawLimit;
  1192. }
  1193.  
  1194. // non-value-transfer getters
  1195. function getTotalCosts() noEther constant returns (uint) {
  1196. return totalCosts;
  1197. }
  1198.  
  1199. function getOneTimeCosts() noEther constant returns (uint) {
  1200. return oneTimeCosts;
  1201. }
  1202.  
  1203. function getMinDailyWithdrawLimit() noEther constant returns (uint128) {
  1204. return minDailyWithdrawLimit;
  1205. }
  1206.  
  1207. function getDailyWithdrawLimit() noEther constant returns (uint128) {
  1208. return dailyWithdrawLimit;
  1209. }
  1210.  
  1211. function getContractor() noEther constant returns (address) {
  1212. return contractor;
  1213. }
  1214.  
  1215. function getHashOfTheProposalDocument() noEther constant returns (bytes32) {
  1216. return hashOfTheProposalDocument;
  1217. }
  1218.  
  1219. function getLastPayment() noEther constant returns (uint) {
  1220. return lastPayment;
  1221. }
  1222.  
  1223. function getDateOfSignature() noEther constant returns (uint) {
  1224. return dateOfSignature;
  1225. }
  1226.  
  1227. function getClient() noEther constant returns (DAO) {
  1228. return client;
  1229. }
  1230.  
  1231. function getOriginalClient() noEther constant returns (DAO) {
  1232. return originalClient;
  1233. }
  1234.  
  1235. function getIsContractValid() noEther constant returns (bool) {
  1236. return isContractValid;
  1237. }
  1238.  
  1239. function sign() {
  1240. if (msg.sender != address(originalClient) // no good samaritans give us ether
  1241. || msg.value != totalCosts // no under/over payment
  1242. || dateOfSignature != 0) // don't sign twice
  1243. throw;
  1244. if (!contractor.send(oneTimeCosts))
  1245. throw;
  1246. dateOfSignature = now;
  1247. isContractValid = true;
  1248. lastPayment = now;
  1249. }
  1250.  
  1251. function setDailyWithdrawLimit(uint128 _dailyWithdrawLimit) onlyClient noEther {
  1252. if (_dailyWithdrawLimit >= minDailyWithdrawLimit)
  1253. dailyWithdrawLimit = _dailyWithdrawLimit;
  1254. }
  1255.  
  1256. // "fire the contractor"
  1257. function returnRemainingEther() onlyClient {
  1258. if (originalClient.DAOrewardAccount().call.value(this.balance)())
  1259. isContractValid = false;
  1260. }
  1261.  
  1262. // Withdraw to the Contractor.
  1263. //
  1264. // Withdraw the amount of ether the Contractor has right to according to
  1265. // the current withdraw limit.
  1266. // Executing this function before the Offer is signed off by the Client
  1267. // makes no sense as this contract has no ether.
  1268. function getDailyPayment() noEther {
  1269. if (msg.sender != contractor)
  1270. throw;
  1271. uint timeSinceLastPayment = now - lastPayment;
  1272. // Calculate the amount using 1 second precision.
  1273. uint amount = (timeSinceLastPayment * dailyWithdrawLimit) / (1 days);
  1274. if (amount > this.balance) {
  1275. amount = this.balance;
  1276. }
  1277. if (contractor.send(amount))
  1278. lastPayment = now;
  1279. }
  1280.  
  1281. // Change the client DAO by giving the new DAO's address
  1282. // warning: The new DAO must come either from a split of the original
  1283. // DAO or an update via `newContract()` so that it can claim rewards
  1284. function updateClientAddress(DAO _newClient) onlyClient noEther {
  1285. client = _newClient;
  1286. }
  1287.  
  1288. function () {
  1289. throw; // this is a business contract, no donations
  1290. }
  1291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement