Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
247 lines (212 sloc) 9.6 KB
pragma solidity ^0.4.8;
contract CryptoPunksMarket {
// You can use this hash to verify the image file containing all the punks
string public imageHash = "ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b";
address owner;
string public standard = 'CryptoPunks';
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
uint public nextPunkIndexToAssign = 0;
bool public allPunksAssigned = false;
uint public punksRemainingToAssign = 0;
//mapping (address => uint) public addressToPunkIndex;
mapping (uint => address) public punkIndexToAddress;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
struct Offer {
bool isForSale;
uint punkIndex;
address seller;
uint minValue; // in ether
address onlySellTo; // specify to sell only to a specific person
}
struct Bid {
bool hasBid;
uint punkIndex;
address bidder;
uint value;
}
// A record of punks that are offered for sale at a specific minimum value, and perhaps to a specific person
mapping (uint => Offer) public punksOfferedForSale;
// A record of the highest punk bid
mapping (uint => Bid) public punkBids;
mapping (address => uint) public pendingWithdrawals;
event Assign(address indexed to, uint256 punkIndex);
event Transfer(address indexed from, address indexed to, uint256 value);
event PunkTransfer(address indexed from, address indexed to, uint256 punkIndex);
event PunkOffered(uint indexed punkIndex, uint minValue, address indexed toAddress);
event PunkBidEntered(uint indexed punkIndex, uint value, address indexed fromAddress);
event PunkBidWithdrawn(uint indexed punkIndex, uint value, address indexed fromAddress);
event PunkBought(uint indexed punkIndex, uint value, address indexed fromAddress, address indexed toAddress);
event PunkNoLongerForSale(uint indexed punkIndex);
/* Initializes contract with initial supply tokens to the creator of the contract */
function CryptoPunksMarket() payable {
// balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
owner = msg.sender;
totalSupply = 10000; // Update total supply
punksRemainingToAssign = totalSupply;
name = "CRYPTOPUNKS"; // Set the name for display purposes
symbol = "Ͼ"; // Set the symbol for display purposes
decimals = 0; // Amount of decimals for display purposes
}
function setInitialOwner(address to, uint punkIndex) {
if (msg.sender != owner) throw;
if (allPunksAssigned) throw;
if (punkIndex >= 10000) throw;
if (punkIndexToAddress[punkIndex] != to) {
if (punkIndexToAddress[punkIndex] != 0x0) {
balanceOf[punkIndexToAddress[punkIndex]]--;
} else {
punksRemainingToAssign--;
}
punkIndexToAddress[punkIndex] = to;
balanceOf[to]++;
Assign(to, punkIndex);
}
}
function setInitialOwners(address[] addresses, uint[] indices) {
if (msg.sender != owner) throw;
uint n = addresses.length;
for (uint i = 0; i < n; i++) {
setInitialOwner(addresses[i], indices[i]);
}
}
function allInitialOwnersAssigned() {
if (msg.sender != owner) throw;
allPunksAssigned = true;
}
function getPunk(uint punkIndex) {
if (!allPunksAssigned) throw;
if (punksRemainingToAssign == 0) throw;
if (punkIndexToAddress[punkIndex] != 0x0) throw;
if (punkIndex >= 10000) throw;
punkIndexToAddress[punkIndex] = msg.sender;
balanceOf[msg.sender]++;
punksRemainingToAssign--;
Assign(msg.sender, punkIndex);
}
// Transfer ownership of a punk to another user without requiring payment
function transferPunk(address to, uint punkIndex) {
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] != msg.sender) throw;
if (punkIndex >= 10000) throw;
if (punksOfferedForSale[punkIndex].isForSale) {
punkNoLongerForSale(punkIndex);
}
punkIndexToAddress[punkIndex] = to;
balanceOf[msg.sender]--;
balanceOf[to]++;
Transfer(msg.sender, to, 1);
PunkTransfer(msg.sender, to, punkIndex);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid bid = punkBids[punkIndex];
if (bid.bidder == to) {
// Kill bid and refund value
pendingWithdrawals[to] += bid.value;
punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
}
}
function punkNoLongerForSale(uint punkIndex) {
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] != msg.sender) throw;
if (punkIndex >= 10000) throw;
punksOfferedForSale[punkIndex] = Offer(false, punkIndex, msg.sender, 0, 0x0);
PunkNoLongerForSale(punkIndex);
}
function offerPunkForSale(uint punkIndex, uint minSalePriceInWei) {
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] != msg.sender) throw;
if (punkIndex >= 10000) throw;
punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, 0x0);
PunkOffered(punkIndex, minSalePriceInWei, 0x0);
}
function offerPunkForSaleToAddress(uint punkIndex, uint minSalePriceInWei, address toAddress) {
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] != msg.sender) throw;
if (punkIndex >= 10000) throw;
punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, toAddress);
PunkOffered(punkIndex, minSalePriceInWei, toAddress);
}
function buyPunk(uint punkIndex) payable {
if (!allPunksAssigned) throw;
Offer offer = punksOfferedForSale[punkIndex];
if (punkIndex >= 10000) throw;
if (!offer.isForSale) throw; // punk not actually for sale
if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) throw; // punk not supposed to be sold to this user
if (msg.value < offer.minValue) throw; // Didn't send enough ETH
if (offer.seller != punkIndexToAddress[punkIndex]) throw; // Seller no longer owner of punk
address seller = offer.seller;
punkIndexToAddress[punkIndex] = msg.sender;
balanceOf[seller]--;
balanceOf[msg.sender]++;
Transfer(seller, msg.sender, 1);
punkNoLongerForSale(punkIndex);
pendingWithdrawals[seller] += msg.value;
PunkBought(punkIndex, msg.value, seller, msg.sender);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid bid = punkBids[punkIndex];
if (bid.bidder == msg.sender) {
// Kill bid and refund value
pendingWithdrawals[msg.sender] += bid.value;
punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
}
}
function withdraw() {
if (!allPunksAssigned) throw;
uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before
// sending to prevent re-entrancy attacks
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
function enterBidForPunk(uint punkIndex) payable {
if (punkIndex >= 10000) throw;
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] == 0x0) throw;
if (punkIndexToAddress[punkIndex] == msg.sender) throw;
if (msg.value == 0) throw;
Bid existing = punkBids[punkIndex];
if (msg.value <= existing.value) throw;
if (existing.value > 0) {
// Refund the failing bid
pendingWithdrawals[existing.bidder] += existing.value;
}
punkBids[punkIndex] = Bid(true, punkIndex, msg.sender, msg.value);
PunkBidEntered(punkIndex, msg.value, msg.sender);
}
function acceptBidForPunk(uint punkIndex, uint minPrice) {
if (punkIndex >= 10000) throw;
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] != msg.sender) throw;
address seller = msg.sender;
Bid bid = punkBids[punkIndex];
if (bid.value == 0) throw;
if (bid.value < minPrice) throw;
punkIndexToAddress[punkIndex] = bid.bidder;
balanceOf[seller]--;
balanceOf[bid.bidder]++;
Transfer(seller, bid.bidder, 1);
punksOfferedForSale[punkIndex] = Offer(false, punkIndex, bid.bidder, 0, 0x0);
uint amount = bid.value;
punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
pendingWithdrawals[seller] += amount;
PunkBought(punkIndex, bid.value, seller, bid.bidder);
}
function withdrawBidForPunk(uint punkIndex) {
if (punkIndex >= 10000) throw;
if (!allPunksAssigned) throw;
if (punkIndexToAddress[punkIndex] == 0x0) throw;
if (punkIndexToAddress[punkIndex] == msg.sender) throw;
Bid bid = punkBids[punkIndex];
if (bid.bidder != msg.sender) throw;
PunkBidWithdrawn(punkIndex, bid.value, msg.sender);
uint amount = bid.value;
punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
// Refund the bid money
msg.sender.transfer(amount);
}
}
You can’t perform that action at this time.