Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.36 KB | None | 0 0
  1. pragma solidity ^0.4.8;
  2.  
  3. contract BetterAuction {
  4. // Mapping for members of multisig
  5. mapping (address => bool) public members;
  6. // Auction start time, seconds from 1970-01-01
  7. uint256 public auctionStart;
  8. // Auction bidding period in seconds, relative to auctionStart
  9. uint256 public biddingPeriod;
  10. // Period after auction ends when the multisig proposals can withdraw all funds, relative to auctionStart
  11. uint256 public recoveryAfterPeriod;
  12. // User sends this amount to the contract to withdraw funds, 0.0001 ETH
  13. uint256 public constant WITHDRAWAL_TRIGGER_AMOUNT = 100000000000000;
  14. // Number of required signatures
  15. uint256 public constant REQUIRED_SIGNATURES = 2;
  16. // Proposal to spend
  17. Proposal[] public proposals;
  18. // Number of proposals
  19. uint256 public numProposals;
  20. // Address of the highest bidder
  21. address public highestBidder;
  22. // Highest bid amount
  23. uint256 public highestBid;
  24. // Allowed withdrawals of previous bids
  25. mapping(address => uint256) pendingReturns;
  26. // Set to true at the end, disallows any change
  27. bool auctionClosed;
  28.  
  29. struct Proposal {
  30. address recipient;
  31. uint256 numVotes;
  32. mapping (address => bool) voted;
  33. bool isRecover;
  34. }
  35.  
  36. modifier isMember {
  37. if (members[msg.sender] == false) throw;
  38. _;
  39. }
  40.  
  41. modifier isAuctionActive {
  42. if (now < auctionStart || now > (auctionStart + biddingPeriod)) throw;
  43. _;
  44. }
  45.  
  46. modifier isAuctionEnded {
  47. if (now < (auctionStart + biddingPeriod)) throw;
  48. _;
  49. }
  50.  
  51. event HighestBidIncreased(address bidder, uint256 amount);
  52. event AuctionClosed(address winner, uint256 amount);
  53. event ProposalAdded(uint proposalID, address recipient);
  54. event Voted(uint proposalID, address voter);
  55.  
  56. // Auction starts at deployment, runs for _biddingPeriod (seconds from
  57. // auction start), and funds can be recovered after _recoverPeriod
  58. // (seconds from auction start)
  59. function BetterAuction(
  60. address _address1,
  61. address _address2,
  62. address _address3,
  63. uint256 _biddingPeriod,
  64. uint256 _recoveryAfterPeriod
  65. ) {
  66. if (_address1 == 0 || _address2 == 0 || _address3 == 0) throw;
  67. members[_address1] = true;
  68. members[_address2] = true;
  69. members[_address3] = true;
  70. auctionStart = now;
  71. if (_biddingPeriod > _recoveryAfterPeriod) throw;
  72. biddingPeriod = _biddingPeriod;
  73. recoveryAfterPeriod = _recoveryAfterPeriod;
  74. }
  75.  
  76. // Users want to know when the auction ends, seconds from 1970-01-01
  77. function auctionEndTime() constant returns (uint256) {
  78. return auctionStart + biddingPeriod;
  79. }
  80.  
  81. // Users want to know theirs or someones current bid
  82. function getBid(address _address) constant returns (uint256) {
  83. if (_address == highestBidder) {
  84. return highestBid;
  85. } else {
  86. return pendingReturns[_address];
  87. }
  88. }
  89.  
  90. // Update highest bid or top up previous bid
  91. function bidderUpdateBid() internal {
  92. if (msg.sender == highestBidder) {
  93. highestBid += msg.value;
  94. HighestBidIncreased(msg.sender, highestBid);
  95. } else if (pendingReturns[msg.sender] + msg.value > highestBid) {
  96. var amount = pendingReturns[msg.sender] + msg.value;
  97. pendingReturns[msg.sender] = 0;
  98. // Save previous highest bidders funds
  99. pendingReturns[highestBidder] = highestBid;
  100. // Record the highest bid
  101. highestBid = amount;
  102. highestBidder = msg.sender;
  103. HighestBidIncreased(msg.sender, amount);
  104. } else {
  105. throw;
  106. }
  107. }
  108.  
  109. // Bidders can only place bid while the auction is active
  110. function bidderPlaceBid() isAuctionActive payable {
  111. if ((pendingReturns[msg.sender] > 0 || msg.sender == highestBidder) && msg.value > 0) {
  112. bidderUpdateBid();
  113. } else {
  114. // Reject bids below the highest bid
  115. if (msg.value <= highestBid) throw;
  116. // Save previous highest bidders funds
  117. if (highestBidder != 0) {
  118. pendingReturns[highestBidder] = highestBid;
  119. }
  120. // Record the highest bid
  121. highestBidder = msg.sender;
  122. highestBid = msg.value;
  123. HighestBidIncreased(msg.sender, msg.value);
  124. }
  125. }
  126.  
  127. // Withdraw a bid that was overbid.
  128. function nonHighestBidderRefund() payable {
  129. var amount = pendingReturns[msg.sender];
  130. if (amount > 0) {
  131. pendingReturns[msg.sender] = 0;
  132. if (!msg.sender.send(amount + msg.value)) throw;
  133. } else {
  134. throw;
  135. }
  136. }
  137.  
  138. // Multisig member creates a proposal to send ether out of the contract
  139. function createProposal (address recipient, bool isRecover) isMember isAuctionEnded {
  140. var proposalID = proposals.length++;
  141. Proposal p = proposals[proposalID];
  142. p.recipient = recipient;
  143. p.voted[msg.sender] = true;
  144. p.numVotes = 1;
  145. numProposals++;
  146. Voted(proposalID, msg.sender);
  147. ProposalAdded(proposalID, recipient);
  148. }
  149.  
  150. // Multisig member votes on a proposal
  151. function voteProposal (uint256 proposalID) isMember isAuctionEnded {
  152. Proposal p = proposals[proposalID];
  153.  
  154. if ( p.voted[msg.sender] ) throw;
  155. p.voted[msg.sender] = true;
  156. p.numVotes++;
  157.  
  158. // Required signatures have been met
  159. if (p.numVotes >= REQUIRED_SIGNATURES) {
  160. if ( p.isRecover ) {
  161. // Is it too early for recovery?
  162. if (now < (auctionStart + recoveryAfterPeriod)) throw;
  163. // Recover any ethers accidentally sent to contract
  164. if (!p.recipient.send(this.balance)) throw;
  165. } else {
  166. if (auctionClosed) throw;
  167. auctionClosed = true;
  168. AuctionClosed(highestBidder, highestBid);
  169. // Send highest bid to recipient
  170. if (!p.recipient.send(highestBid)) throw;
  171. }
  172. }
  173. }
  174.  
  175. // Bidders send their bids to the contract. If this is the trigger amount
  176. // allow non-highest bidders to withdraw their funds
  177. function () payable {
  178. if (msg.value == WITHDRAWAL_TRIGGER_AMOUNT) {
  179. nonHighestBidderRefund();
  180. } else {
  181. bidderPlaceBid();
  182. }
  183. }
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement