github.com/diadata-org/diadata@v1.4.593/config/nftContracts/cryptopunk/cryptopunk.sol (about) 1 /** 2 *Submitted for verification at Etherscan.io on 2017-07-19 3 */ 4 5 pragma solidity ^0.4.8; 6 contract CryptoPunksMarket { 7 8 // You can use this hash to verify the image file containing all the punks 9 string public imageHash = "ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b"; 10 11 address owner; 12 13 string public standard = 'CryptoPunks'; 14 string public name; 15 string public symbol; 16 uint8 public decimals; 17 uint256 public totalSupply; 18 19 uint public nextPunkIndexToAssign = 0; 20 21 bool public allPunksAssigned = false; 22 uint public punksRemainingToAssign = 0; 23 24 //mapping (address => uint) public addressToPunkIndex; 25 mapping (uint => address) public punkIndexToAddress; 26 27 /* This creates an array with all balances */ 28 mapping (address => uint256) public balanceOf; 29 30 struct Offer { 31 bool isForSale; 32 uint punkIndex; 33 address seller; 34 uint minValue; // in ether 35 address onlySellTo; // specify to sell only to a specific person 36 } 37 38 struct Bid { 39 bool hasBid; 40 uint punkIndex; 41 address bidder; 42 uint value; 43 } 44 45 // A record of punks that are offered for sale at a specific minimum value, and perhaps to a specific person 46 mapping (uint => Offer) public punksOfferedForSale; 47 48 // A record of the highest punk bid 49 mapping (uint => Bid) public punkBids; 50 51 mapping (address => uint) public pendingWithdrawals; 52 53 event Assign(address indexed to, uint256 punkIndex); 54 event Transfer(address indexed from, address indexed to, uint256 value); 55 event PunkTransfer(address indexed from, address indexed to, uint256 punkIndex); 56 event PunkOffered(uint indexed punkIndex, uint minValue, address indexed toAddress); 57 event PunkBidEntered(uint indexed punkIndex, uint value, address indexed fromAddress); 58 event PunkBidWithdrawn(uint indexed punkIndex, uint value, address indexed fromAddress); 59 event PunkBought(uint indexed punkIndex, uint value, address indexed fromAddress, address indexed toAddress); 60 event PunkNoLongerForSale(uint indexed punkIndex); 61 62 /* Initializes contract with initial supply tokens to the creator of the contract */ 63 function CryptoPunksMarket() payable { 64 // balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens 65 owner = msg.sender; 66 totalSupply = 10000; // Update total supply 67 punksRemainingToAssign = totalSupply; 68 name = "CRYPTOPUNKS"; // Set the name for display purposes 69 symbol = "ΟΎ"; // Set the symbol for display purposes 70 decimals = 0; // Amount of decimals for display purposes 71 } 72 73 function setInitialOwner(address to, uint punkIndex) { 74 if (msg.sender != owner) throw; 75 if (allPunksAssigned) throw; 76 if (punkIndex >= 10000) throw; 77 if (punkIndexToAddress[punkIndex] != to) { 78 if (punkIndexToAddress[punkIndex] != 0x0) { 79 balanceOf[punkIndexToAddress[punkIndex]]--; 80 } else { 81 punksRemainingToAssign--; 82 } 83 punkIndexToAddress[punkIndex] = to; 84 balanceOf[to]++; 85 Assign(to, punkIndex); 86 } 87 } 88 89 function setInitialOwners(address[] addresses, uint[] indices) { 90 if (msg.sender != owner) throw; 91 uint n = addresses.length; 92 for (uint i = 0; i < n; i++) { 93 setInitialOwner(addresses[i], indices[i]); 94 } 95 } 96 97 function allInitialOwnersAssigned() { 98 if (msg.sender != owner) throw; 99 allPunksAssigned = true; 100 } 101 102 function getPunk(uint punkIndex) { 103 if (!allPunksAssigned) throw; 104 if (punksRemainingToAssign == 0) throw; 105 if (punkIndexToAddress[punkIndex] != 0x0) throw; 106 if (punkIndex >= 10000) throw; 107 punkIndexToAddress[punkIndex] = msg.sender; 108 balanceOf[msg.sender]++; 109 punksRemainingToAssign--; 110 Assign(msg.sender, punkIndex); 111 } 112 113 // Transfer ownership of a punk to another user without requiring payment 114 function transferPunk(address to, uint punkIndex) { 115 if (!allPunksAssigned) throw; 116 if (punkIndexToAddress[punkIndex] != msg.sender) throw; 117 if (punkIndex >= 10000) throw; 118 if (punksOfferedForSale[punkIndex].isForSale) { 119 punkNoLongerForSale(punkIndex); 120 } 121 punkIndexToAddress[punkIndex] = to; 122 balanceOf[msg.sender]--; 123 balanceOf[to]++; 124 Transfer(msg.sender, to, 1); 125 PunkTransfer(msg.sender, to, punkIndex); 126 // Check for the case where there is a bid from the new owner and refund it. 127 // Any other bid can stay in place. 128 Bid bid = punkBids[punkIndex]; 129 if (bid.bidder == to) { 130 // Kill bid and refund value 131 pendingWithdrawals[to] += bid.value; 132 punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0); 133 } 134 } 135 136 function punkNoLongerForSale(uint punkIndex) { 137 if (!allPunksAssigned) throw; 138 if (punkIndexToAddress[punkIndex] != msg.sender) throw; 139 if (punkIndex >= 10000) throw; 140 punksOfferedForSale[punkIndex] = Offer(false, punkIndex, msg.sender, 0, 0x0); 141 PunkNoLongerForSale(punkIndex); 142 } 143 144 function offerPunkForSale(uint punkIndex, uint minSalePriceInWei) { 145 if (!allPunksAssigned) throw; 146 if (punkIndexToAddress[punkIndex] != msg.sender) throw; 147 if (punkIndex >= 10000) throw; 148 punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, 0x0); 149 PunkOffered(punkIndex, minSalePriceInWei, 0x0); 150 } 151 152 function offerPunkForSaleToAddress(uint punkIndex, uint minSalePriceInWei, address toAddress) { 153 if (!allPunksAssigned) throw; 154 if (punkIndexToAddress[punkIndex] != msg.sender) throw; 155 if (punkIndex >= 10000) throw; 156 punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, toAddress); 157 PunkOffered(punkIndex, minSalePriceInWei, toAddress); 158 } 159 160 function buyPunk(uint punkIndex) payable { 161 if (!allPunksAssigned) throw; 162 Offer offer = punksOfferedForSale[punkIndex]; 163 if (punkIndex >= 10000) throw; 164 if (!offer.isForSale) throw; // punk not actually for sale 165 if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) throw; // punk not supposed to be sold to this user 166 if (msg.value < offer.minValue) throw; // Didn't send enough ETH 167 if (offer.seller != punkIndexToAddress[punkIndex]) throw; // Seller no longer owner of punk 168 169 address seller = offer.seller; 170 171 punkIndexToAddress[punkIndex] = msg.sender; 172 balanceOf[seller]--; 173 balanceOf[msg.sender]++; 174 Transfer(seller, msg.sender, 1); 175 176 punkNoLongerForSale(punkIndex); 177 pendingWithdrawals[seller] += msg.value; 178 PunkBought(punkIndex, msg.value, seller, msg.sender); 179 180 // Check for the case where there is a bid from the new owner and refund it. 181 // Any other bid can stay in place. 182 Bid bid = punkBids[punkIndex]; 183 if (bid.bidder == msg.sender) { 184 // Kill bid and refund value 185 pendingWithdrawals[msg.sender] += bid.value; 186 punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0); 187 } 188 } 189 190 function withdraw() { 191 if (!allPunksAssigned) throw; 192 uint amount = pendingWithdrawals[msg.sender]; 193 // Remember to zero the pending refund before 194 // sending to prevent re-entrancy attacks 195 pendingWithdrawals[msg.sender] = 0; 196 msg.sender.transfer(amount); 197 } 198 199 function enterBidForPunk(uint punkIndex) payable { 200 if (punkIndex >= 10000) throw; 201 if (!allPunksAssigned) throw; 202 if (punkIndexToAddress[punkIndex] == 0x0) throw; 203 if (punkIndexToAddress[punkIndex] == msg.sender) throw; 204 if (msg.value == 0) throw; 205 Bid existing = punkBids[punkIndex]; 206 if (msg.value <= existing.value) throw; 207 if (existing.value > 0) { 208 // Refund the failing bid 209 pendingWithdrawals[existing.bidder] += existing.value; 210 } 211 punkBids[punkIndex] = Bid(true, punkIndex, msg.sender, msg.value); 212 PunkBidEntered(punkIndex, msg.value, msg.sender); 213 } 214 215 function acceptBidForPunk(uint punkIndex, uint minPrice) { 216 if (punkIndex >= 10000) throw; 217 if (!allPunksAssigned) throw; 218 if (punkIndexToAddress[punkIndex] != msg.sender) throw; 219 address seller = msg.sender; 220 Bid bid = punkBids[punkIndex]; 221 if (bid.value == 0) throw; 222 if (bid.value < minPrice) throw; 223 224 punkIndexToAddress[punkIndex] = bid.bidder; 225 balanceOf[seller]--; 226 balanceOf[bid.bidder]++; 227 Transfer(seller, bid.bidder, 1); 228 229 punksOfferedForSale[punkIndex] = Offer(false, punkIndex, bid.bidder, 0, 0x0); 230 uint amount = bid.value; 231 punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0); 232 pendingWithdrawals[seller] += amount; 233 PunkBought(punkIndex, bid.value, seller, bid.bidder); 234 } 235 236 function withdrawBidForPunk(uint punkIndex) { 237 if (punkIndex >= 10000) throw; 238 if (!allPunksAssigned) throw; 239 if (punkIndexToAddress[punkIndex] == 0x0) throw; 240 if (punkIndexToAddress[punkIndex] == msg.sender) throw; 241 Bid bid = punkBids[punkIndex]; 242 if (bid.bidder != msg.sender) throw; 243 PunkBidWithdrawn(punkIndex, bid.value, msg.sender); 244 uint amount = bid.value; 245 punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0); 246 // Refund the bid money 247 msg.sender.transfer(amount); 248 } 249 250 }