pragma solidity ^0.4.24; import "./ERC721Asset.sol"; import "./SafeMath.sol"; import "./Ownable.sol"; contract TradingCardSet is Ownable { using SafeMath for uint256; // Set name string internal name_; // Address where funds are collected address public wallet; address[] public tradingCardContracts; mapping(bytes32 => address) private codeHashToCardAddressMapping; mapping(bytes32 => uint256) private codeHashToTokenIdMapping; uint256 public pricePerCard = 50 finney; uint16 private totalWeight; mapping(uint16 => address) private diceRollToCard; bytes32 private lastHash; constructor(address _wallet, string _name) public Ownable() { wallet = _wallet; name_ = _name; lastHash = keccak256(block.timestamp, block.difficulty, block.number); } /** * @dev Gets the set name * @return string representing the set name */ function name() external view returns (string) { return name_; } function setPricePerCard(uint256 _pricePerCard) public onlyOwner { pricePerCard = _pricePerCard; } function addTradingCard(address _cardAddress, uint8 _rarityWeight) public onlyOwner { require(_cardAddress != address(0)); require(_rarityWeight > 0); tradingCardContracts.push(_cardAddress); uint16 lowerBound = totalWeight; totalWeight += _rarityWeight; uint16 upperBound = totalWeight; for (uint16 j = lowerBound; j < upperBound; j++) { diceRollToCard[j] = _cardAddress; } } function getTradingCardContracts() public view returns (address[]) { return tradingCardContracts; } /** * @dev fallback function ***DO NOT OVERRIDE*** */ function() external payable { purchaseCard(msg.sender); } function purchaseCard(address beneficiary) public payable { require(beneficiary != address(0)); require(msg.value >= pricePerCard); uint16 randomNumber = randomUINT16(0, totalWeight, msg.sender); ERC721Asset selectedCardToken = ERC721Asset( diceRollToCard[randomNumber] ); selectedCardToken.mint(beneficiary, selectedCardToken.amountMinted()); uint256 change = msg.value - pricePerCard; //This amount to be refunded as it was unused _forwardFunds(pricePerCard); _refundChange(change); } function burnCard(address _cardAddress, uint256 _tokenId) public onlyOwner { require(_cardAddress != address(0)); ERC721Asset card = ERC721Asset(_cardAddress); card.burn(owner, _tokenId); } function mintPhysicalCard(address _cardAddress, bytes32 _redemptionCodeHash) public onlyOwner { ERC721Asset card = ERC721Asset(_cardAddress); uint256 mintedTokenId = card.amountMinted(); card.mint(address(this), mintedTokenId); codeHashToCardAddressMapping[_redemptionCodeHash] = _cardAddress; codeHashToTokenIdMapping[_redemptionCodeHash] = mintedTokenId; } function redeemPhysicalCard(address _beneficiary, string _redemptionCode) public { require(_beneficiary != address(0)); bytes32 redemptionCodeHash = sha256(_redemptionCode); address cardToRedeem = codeHashToCardAddressMapping[redemptionCodeHash]; require(cardToRedeem != address(0)); uint256 tokenIdToRedeem = codeHashToTokenIdMapping[redemptionCodeHash]; // At this point, we can transfer ownership of the card to the beneficiary ERC721Asset card = ERC721Asset(cardToRedeem); card.doSafeTransferTo(_beneficiary, tokenIdToRedeem); // The redemption code is used up - remove it so the card can't be redeemed again codeHashToCardAddressMapping[redemptionCodeHash] = address(0); codeHashToTokenIdMapping[redemptionCodeHash] = uint256(0); } function randomUINT16(uint16 _min, uint16 _max, address _sender) internal returns (uint16) { require(_min < _max); uint16 range = _max - _min; lastHash = keccak256( block.timestamp, block.difficulty, block.number, lastHash, _sender ); return _min + uint16(uint256(lastHash) % range); } function _forwardFunds(uint256 amount) internal { wallet.transfer(amount); } function _refundChange(uint256 amount) internal { msg.sender.transfer(amount); } }
0.4.24