Transaction Hash:
Block:
10916714 at Sep-23-2020 04:44:35 AM +UTC
Transaction Fee:
0.00719328 ETH
$17.85
Gas Used:
74,930 Gas / 96 Gwei
Emitted Events:
79 |
MEXPToken.Transfer( from=0x0000000000000000000000000000000000000000, to=[Sender] 0xb987700d4152c27b9bbfbdd6041ebdd248c174c4, value=10795392361107311133 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x005e288D...8688C7223
Miner
| (xnpool) | 356.191131568876985471 Eth | 356.198324848876985471 Eth | 0.00719328 | |
0x99588e87...5Be71A92F | 31.989253 Eth | 32.024253 Eth | 0.035 | ||
0xB987700d...248c174C4 |
4.857235049764582952 Eth
Nonce: 1195
|
4.815041769764582952 Eth
Nonce: 1196
| 0.04219328 | ||
0xDe201dAe...28E270F06 |
Execution Trace
ETH 0.035
MEXPToken.mintToken( _tokenID=1558 ) => ( True )

-
Niftymoji.ownerOf( tokenId=1558 ) => ( 0xB987700d4152c27b9bBfbdd6041Ebdd248c174C4 )
-
Niftymoji.powerNLucks( 1558 ) => ( power=23, luck=97 )
- ETH 0.035
0x99588e879b146cfc51628fef1e3715d5be71a92f.CALL( )
File 1 of 2: MEXPToken
File 2 of 2: Niftymoji
pragma solidity 0.5.16; /* ___________________________________________________________________ _ _ ______ | | / / / --|-/|-/-----__---/----__----__---_--_----__-------/-------__------ |/ |/ /___) / / ' / ) / / ) /___) / / ) __/__|____(___ _/___(___ _(___/_/_/__/_(___ _____/______(___/__o_o_ ███╗ ███╗███████╗██╗ ██╗██████╗ ████████╗ ██████╗ ██╗ ██╗███████╗███╗ ██╗ ████╗ ████║██╔════╝╚██╗██╔╝██╔══██╗ ╚══██╔══╝██╔═══██╗██║ ██╔╝██╔════╝████╗ ██║ ██╔████╔██║█████╗ ╚███╔╝ ██████╔╝ ██║ ██║ ██║█████╔╝ █████╗ ██╔██╗ ██║ ██║╚██╔╝██║██╔══╝ ██╔██╗ ██╔═══╝ ██║ ██║ ██║██╔═██╗ ██╔══╝ ██║╚██╗██║ ██║ ╚═╝ ██║███████╗██╔╝ ██╗██║ ██║ ╚██████╔╝██║ ██╗███████╗██║ ╚████║ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ === 'MEXP' Token contract with following features === => TRC20 Compliance => Higher degree of control by owner - safeguard functionality => SafeMath implementation => Burnable and minting ( For MOJI Players) ======================= Quick Stats =================== => Name : "MOJI Experience Points" => Symbol : MEXP => Total supply: 0 (Minted only by MOJI players only) => Decimals : 18 */ //*******************************************************************// //------------------------ SafeMath Library -------------------------// //*******************************************************************// /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } } //*******************************************************************// //------------------ Contract to Manage Ownership -------------------// //*******************************************************************// contract owned { address payable public owner; address payable private newOwner; /** Signer is deligated admin wallet, which can do sub-owner functions. Signer calls following four functions: => claimOwnerTokens => distributeMainDividend => distributeLeaders1 => distributeLeaders2 */ address public signer; event OwnershipTransferred(address indexed _from, address indexed _to); constructor() public { owner = msg.sender; signer = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } modifier onlySigner { require(msg.sender == signer); _; } function changeSigner(address _signer) public onlyOwner { signer = _signer; } function transferOwnership(address payable _newOwner) public onlyOwner { newOwner = _newOwner; } //this flow is to prevent transferring ownership to wrong wallet by mistake function acceptOwnership() public { require(msg.sender == newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; newOwner = address(0); } } //**************************************************************************// //------------------- NIFTYMOJI CONTRACT INTERFACE --------------------// //**************************************************************************// interface niftyMoji { function ownerOf(uint256 tokenId) external view returns (address); function powerNLucks(uint256 tokenID) external view returns(uint256, uint256); function totalSupply() external view returns(uint256); } //****************************************************************************// //--------------------- MEXP MAIN CODE STARTS HERE ---------------------// //****************************************************************************// contract MEXPToken is owned { /*=============================== = DATA STORAGE = ===============================*/ // Public variables of the token using SafeMath for uint256; uint256 public withdrawnByAdmin; string public constant name = "MOJI Experience Points"; string public constant symbol = "MEXP"; uint256 public constant decimals = 18; uint256 public totalSupply; uint256 public burnTracker; //mainly used in mintToken function.. uint256 public mintingMultiplier=10000; // 10000 = 1, 123 = 0.0123 admin can set it minting per day, will be factored as luck % address public niftyMojiContractAddress = 0xde544E54a330Abd1eA8a0E6693D46BFe95D9A684; // admin can set / change this address uint256 public battleFees=1; // default is 0.000000000000000001 Ether for battle fees, which admin can change uint256 public mintTokenFee = 0.001 ether; uint256 public battleWinReward= 10**18; // = 1 token with 18 decimal places, admin can change uint256 public battleLooseReward = 10**17; // = 0.1 token with 10 decimal places, admin can change uint256 public maxBattlePerDay=10; //daily 10 max battles bool public globalHalt; // Emergency Break uint256 public lastFinishedIndex; // This creates a mapping with all data storage mapping (address => uint256) public balanceOf; mapping(uint256 => uint256) public totalMintedForTokenId; mapping(uint256 => uint256) public totalMintedByOwnerForTokenID; mapping(uint256 => uint256) public totalMintedByUserForTokenID; mapping(uint256 => uint256) public totalMintedByBattleForTokenID; mapping(uint256 => uint256) public dayTracker; mapping (address => mapping (address => uint256)) public allowance; mapping(address => uint256) public BattleCountEndTime; mapping (address => uint256) public userBattleCount; mapping(address => bool) public blackListedUser; mapping(uint256 => bool) public blackListedToken; struct battleInfo { uint256 tokenID; uint256 userSeed; uint256 rewardAmount; uint256 blockNo; uint256 opponentTokenID; } battleInfo[] public battleInfos; /*=============================== = PUBLIC EVENTS = ===============================*/ // This generates a public event of token transfer event Transfer(address indexed from, address indexed to, uint256 value); // This notifies clients about the amount burnt event Burn(address indexed indexed from, uint256 value); // This trackes approvals event Approval(address indexed owner, address indexed spender, uint256 value ); /*====================================== = STANDARD TRC20 FUNCTIONS = ======================================*/ /* Internal transfer, only can be called by this contract */ function _transfer(address _from, address _to, uint _value) internal { //checking conditions require(!globalHalt, "paused by admin"); require (_to != address(0x0)); // Prevent transfer to 0x0 address. Use burn() instead // overflow and undeflow checked by SafeMath Library balanceOf[_from] = balanceOf[_from].sub(_value); // Subtract from the sender balanceOf[_to] = balanceOf[_to].add(_value); // Add the same to the recipient // emit Transfer event emit Transfer(_from, _to, _value); } /** * Transfer tokens * * Send `_value` tokens to `_to` from your account * * @param _to The address of the recipient * @param _value the amount to send */ function transfer(address _to, uint256 _value) public returns (bool success) { require(!blackListedUser[msg.sender], "you are not allowed"); //no need to check for input validations, as that is ruled by SafeMath _transfer(msg.sender, _to, _value); return true; } /** * Transfer tokens from other address * * Send `_value` tokens to `_to` in behalf of `_from` * * @param _from The address of the sender * @param _to The address of the recipient * @param _value the amount to send */ function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(!blackListedUser[msg.sender], "you are not allowed"); //require(_value <= allowance[_from][msg.sender]); // no need for this condition as it is already checked by SafeMath below allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value); _transfer(_from, _to, _value); return true; } /** * Set allowance for other address * * Allows `_spender` to spend no more than `_value` tokens in your behalf * * @param _spender The address authorized to spend * @param _value the max amount they can spend */ function approve(address _spender, uint256 _value) public returns (bool success) { require(!blackListedUser[msg.sender], "you are not allowed"); require(!globalHalt, "paused by admin"); allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /*===================================== = CUSTOM PUBLIC FUNCTIONS = ======================================*/ /** Constructor function */ constructor() public { battleInfo memory temp; battleInfos.push(temp); } /** * Fallback function. It just accepts incoming Ether */ function () payable external {} /** * Destroy tokens * * Remove `_value` tokens from the system irreversibly * * @param _value the amount of money to burn */ function burn(uint256 _value) public returns (bool success) { require(!globalHalt, "paused by admin"); require(!blackListedUser[msg.sender], "you are not allowed"); //checking of enough token balance is done by SafeMath balanceOf[msg.sender] = balanceOf[msg.sender].sub(_value); // Subtract from the sender totalSupply = totalSupply.sub(_value); // Updates totalSupply burnTracker = burnTracker.add(_value); emit Transfer(msg.sender, address(0), _value); //althogh we can track all the "burn" from the Transfer function, we just kept it as it is. As that is no much harm emit Burn(msg.sender, _value); return true; } /** * Destroy tokens from other account * * Remove `_value` tokens from the system irreversibly on behalf of `_from`. * * @param _from the address of the sender * @param _value the amount of money to burn */ function burnFrom(address _from, uint256 _value) public returns (bool success) { require(!globalHalt, "paused by admin"); require(!blackListedUser[msg.sender], "you are not allowed"); //checking of allowance and token value is done by SafeMath balanceOf[_from] = balanceOf[_from].sub(_value); // Subtract from the targeted balance allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value); // Subtract from the sender's allowance totalSupply = totalSupply.sub(_value); // Update totalSupply burnTracker = burnTracker.add(_value); emit Transfer(_from, address(0), _value); emit Burn(_from, _value); return true; } function mintTokenOwnerOnly(address user, uint256 _tokenID, uint256 tokenAmount) public onlyOwner returns(bool) { require(user != address(this) && user != address(0), "invalid address" ); require(tokenAmount > 0 , "Invalid token to mint"); require(!blackListedToken[_tokenID], "this token is blacklisted"); if(_tokenID != 0) { require(niftyMoji(niftyMojiContractAddress).ownerOf(_tokenID) == user,"user is not the owner of this tokenID"); totalMintedForTokenId[_tokenID] = totalMintedForTokenId[_tokenID].add(tokenAmount); totalMintedByOwnerForTokenID[_tokenID] = totalMintedByOwnerForTokenID[_tokenID].add(tokenAmount); } totalSupply = totalSupply.add(tokenAmount); balanceOf[user] = balanceOf[user].add(tokenAmount); //emitting Transfer event emit Transfer(address(0),user,tokenAmount); return true; } function blackListUser(address user) public onlyOwner returns(bool) { blackListedUser[user] = true; return true; } function removeUserFromBlackList(address user) public onlyOwner returns(bool) { blackListedUser[user] = false; return true; } function blackListToken(uint256 _tokenID) public onlyOwner returns(bool) { blackListedToken[_tokenID] = true; return true; } function removeTokenFromBlackList(uint256 _tokenID) public onlyOwner returns(bool) { blackListedToken[_tokenID] = false; return true; } //Minting according to luck percent of the given token id function mintToken(uint256 _tokenID) public payable returns(bool) { require(!globalHalt, "paused by admin"); address caller = niftyMoji(niftyMojiContractAddress).ownerOf(_tokenID); require(!blackListedUser[caller], "you are not allowed"); require(!blackListedToken[_tokenID], "this token is blacklisted"); require(caller == msg.sender,"caller is not the owner of this tokenID"); require(msg.value >= mintTokenFee, 'Not enough token minting fee'); uint256 dt = dayTracker[_tokenID]; if (dt != 0) { uint256 secPassed = now - dt ; require(secPassed > 0 , "already minted for the day"); (,uint256 luckPercent ) = niftyMoji(niftyMojiContractAddress).powerNLucks(_tokenID); uint256 mintAmount = (( (mintingMultiplier * (10 ** 18) * ((luckPercent + 9 ) / 10 ) ) / 100000 ) / 86400 ) * secPassed ; dayTracker[_tokenID] = now ; totalMintedByUserForTokenID[_tokenID] = totalMintedByUserForTokenID[_tokenID].add(mintAmount); totalMintedForTokenId[_tokenID] = totalMintedForTokenId[_tokenID].add(mintAmount); totalSupply = totalSupply.add(mintAmount); balanceOf[caller] = balanceOf[caller].add(mintAmount); //emitting Transfer event emit Transfer(address(0),caller,mintAmount); } else { dayTracker[_tokenID] = now; } owner.transfer(msg.value); return true; } function viewAmountIfIMintNow(uint256 _tokenID) public view returns(uint256 amount) { uint256 dt = dayTracker[_tokenID]; if (dt != 0) { uint256 secPassed = now - dt ; (,uint256 luckPercent ) = niftyMoji(niftyMojiContractAddress).powerNLucks(_tokenID); amount = (( (mintingMultiplier * (10 ** 18) * ((luckPercent + 9 ) / 10 ) ) / 100000 ) / 86400 ) * secPassed ; return amount; } else { return (0); } } function setMaxBattlePerDay(uint _maxBattlePerDay) public onlyOwner returns (bool) { maxBattlePerDay = _maxBattlePerDay; return true; } event initiateBattleEv(address caller,uint256 _tokenID,uint256 _userSeed,uint256 battleInfoIndex, uint256 blockNo); function initiateBattle(uint256 _tokenID, uint256 _userSeed) public payable returns (uint256 battleID) { require(!globalHalt, "paused by admin"); require(msg.value == battleFees, "Invalid fees amount"); address caller = niftyMoji(niftyMojiContractAddress).ownerOf(_tokenID); require(!blackListedUser[caller], "you are not allowed"); require(!blackListedToken[_tokenID], "this token is blacklisted"); require(caller == msg.sender,"caller is not the owner of this tokenID"); require( userBattleCount[caller] <= maxBattlePerDay, "enough for the day"); if(BattleCountEndTime[caller] >= now ) { userBattleCount[caller] += 1; } else { BattleCountEndTime[caller] = now + 86400; userBattleCount[caller] = 1; } battleInfo memory temp; temp.tokenID = _tokenID; temp.userSeed = _userSeed; temp.blockNo = block.number; battleInfos.push(temp); //emitting Transfer event battleID = battleInfos.length - 1; address(owner).transfer(msg.value); emit initiateBattleEv(caller, _tokenID, _userSeed, battleID,block.number ); return battleID; } event finishBattleEv(address user, uint256 battleInfoIndex, uint256 _tokenID, uint256 randomToken, uint256 mintAmount); function finishBattle(uint256 _battleInfoIndex,bytes32 blockHashValue) public onlySigner returns (bool) // returns winning amount minted { require(_battleInfoIndex < battleInfos.length, "Invalid Battle Index"); require(battleInfos[_battleInfoIndex].rewardAmount == 0, "Already finished"); uint256 _tokenID = battleInfos[_battleInfoIndex].tokenID; uint256 _userSeed = battleInfos[_battleInfoIndex].userSeed; address caller = niftyMoji(niftyMojiContractAddress).ownerOf(_tokenID); bool success; uint256 randomToken; address randomTokenUser; for(uint256 i=0;i<50;i++) { randomToken = uint256(keccak256(abi.encodePacked(blockHashValue, _userSeed))) % niftyMoji(niftyMojiContractAddress).totalSupply() + 1; randomTokenUser = niftyMoji(niftyMojiContractAddress).ownerOf(_tokenID); if(blackListedToken[randomToken] || blackListedUser[randomTokenUser]) { _userSeed += block.number%8; } else { success = true; break; } } require(success, "try again"); (uint256 powerPercent,uint256 luckPercent ) = niftyMoji(niftyMojiContractAddress).powerNLucks(_tokenID); (uint256 powerPercent2,uint256 luckPercent2 ) = niftyMoji(niftyMojiContractAddress).powerNLucks(randomToken); uint256 mintAmount; if( powerPercent + luckPercent > powerPercent2 + luckPercent2) { mintAmount = battleWinReward ; } else { mintAmount = battleLooseReward; } battleInfos[_battleInfoIndex].rewardAmount = mintAmount; battleInfos[_battleInfoIndex].opponentTokenID = randomToken; emit finishBattleEv(caller,_battleInfoIndex, _tokenID, randomToken, mintAmount); balanceOf[caller] = balanceOf[caller].add(mintAmount); totalSupply = totalSupply.add(mintAmount); totalMintedForTokenId[_tokenID] = totalMintedForTokenId[_tokenID].add(mintAmount); totalMintedByBattleForTokenID[_tokenID] = totalMintedByBattleForTokenID[_tokenID].add(mintAmount); dayTracker[_tokenID] = now; lastFinishedIndex = _battleInfoIndex; emit Transfer(address(0),caller,mintAmount); return true; } function multipleFinishBattle (bytes32[] memory _blockHashValue) public onlySigner returns(bool) { uint i; for(i=0;i<_blockHashValue.length;i++) { require(finishBattle(lastFinishedIndex + i + 1,_blockHashValue[i]),"could not fihish battle"); } return true; } function lastUnFinishedIndexNBlock() public view returns (uint256 lastUnFinishedIndex, uint256 blockNo) { uint len = battleInfos.length-1; if(len > lastFinishedIndex) { return (lastFinishedIndex +1, battleInfos[lastFinishedIndex +1].blockNo); } else { return (0,0); } } function setNiftyMojiContractAddress(address _niftyMojiContractAddress) public onlyOwner returns(bool) { niftyMojiContractAddress = _niftyMojiContractAddress; return true; } function setMintingMultiplier(uint256 _mintingMultiplier) public onlyOwner returns (bool) { mintingMultiplier = _mintingMultiplier; return true; } function setbattleFees(uint256 _battleFees) public onlyOwner returns(bool) { battleFees = _battleFees; return true; } function setMintTokenFee(uint256 _mintTokenFee) public onlyOwner returns(bool) { mintTokenFee = _mintTokenFee; return true; } function setBattleReward(uint256 winReward, uint256 looseReward) public onlyOwner returns(bool) { battleWinReward = winReward; battleLooseReward = looseReward; return true; } /** * If global halt is off, then this funtion will on it. And vice versa * This also change safeguard for token movement status */ function changeGlobalHalt() onlyOwner public returns(bool) { if (globalHalt == false){ globalHalt = true; } else{ globalHalt = false; } return true; } /** * Function to check Ether balance in this contract */ function totalEtherbalanceContract() public view returns(uint256){ return address(this).balance; } /** * Just in rare case, owner wants to transfer Ether from contract to owner address */ function manualWithdrawEtherAdmin(uint64 Amount) public onlyOwner returns (bool){ require (address(this).balance >= Amount); address(owner).transfer(Amount); withdrawnByAdmin = withdrawnByAdmin.add(Amount); return true; } }
File 2 of 2: Niftymoji
pragma solidity ^0.5.16; /* ___________________________________________________________________ _ _ ______ | | / / / --|-/|-/-----__---/----__----__---_--_----__-------/-------__------ |/ |/ /___) / / ' / ) / / ) /___) / / ) __/__|____(___ _/___(___ _(___/_/_/__/_(___ _____/______(___/__o_o_ ███╗ ██╗██╗███████╗████████╗██╗ ██╗ ███╗ ███╗ ██████╗ ██╗██╗ ████╗ ██║██║██╔════╝╚══██╔══╝╚██╗ ██╔╝ ████╗ ████║██╔═══██╗ ██║██║ ██╔██╗ ██║██║█████╗ ██║ ╚████╔╝ ██╔████╔██║██║ ██║ ██║██║ ██║╚██╗██║██║██╔══╝ ██║ ╚██╔╝ ██║╚██╔╝██║██║ ██║██ ██║██║ ██║ ╚████║██║██║ ██║ ██║ ██║ ╚═╝ ██║╚██████╔╝╚█████╔╝██║ ╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚════╝ ╚═╝ === 'Niftymoji' NFT Management contract with following features === => ERC721 Compliance => ERC165 Compliance => SafeMath implementation => Generation of new digital assets => Destroyal of digital assets ============= Independant Audit of the code ============ => Multiple Freelancers Auditors ------------------------------------------------------------------- Copyright (c) 2019 onwards Niftymoji Inc. ( https://niftymoji.com ) ------------------------------------------------------------------- */ /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address payable internal _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. * @notice Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address payable newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address payable newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/Strings.sol pragma solidity ^0.5.2; library Strings { // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory _bc = bytes(_c); bytes memory _bd = bytes(_d); bytes memory _be = bytes(_e); string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); bytes memory babcde = bytes(abcde); uint k = 0; for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; for (uint i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; for (uint i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; for (uint i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; for (uint i = 0; i < _be.length; i++) babcde[k++] = _be[i]; return string(babcde); } function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory) { return strConcat(_a, _b, _c, _d, ""); } function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) { return strConcat(_a, _b, _c, "", ""); } function strConcat(string memory _a, string memory _b) internal pure returns (string memory) { return strConcat(_a, _b, "", "", ""); } function uint2str(uint _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint j = _i; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (_i != 0) { bstr[k--] = byte(uint8(48 + _i % 10)); _i /= 10; } return string(bstr); } function fromAddress(address addr) internal pure returns(string memory) { bytes20 addrBytes = bytes20(addr); bytes16 hexAlphabet = "0123456789abcdef"; bytes memory result = new bytes(42); result[0] = '0'; result[1] = 'x'; for (uint i = 0; i < 20; i++) { result[i * 2 + 2] = hexAlphabet[uint8(addrBytes[i] >> 4)]; result[i * 2 + 3] = hexAlphabet[uint8(addrBytes[i] & 0x0f)]; } return string(result); } } // File: openzeppelin-solidity/contracts/introspection/IERC165.sol pragma solidity ^0.5.2; /** * @title IERC165 * @dev https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 { /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol pragma solidity ^0.5.2; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.5.2; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safeTransfer`. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public returns (bytes4); } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.2; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: openzeppelin-solidity/contracts/utils/Address.sol pragma solidity ^0.5.2; /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: openzeppelin-solidity/contracts/drafts/Counters.sol pragma solidity ^0.5.2; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } // File: openzeppelin-solidity/contracts/introspection/ERC165.sol pragma solidity ^0.5.2; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /* * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor () internal { _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); _supportedInterfaces[interfaceId] = true; } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol pragma solidity ^0.5.2; interface OldNiftymoji{ function powerNLucks(uint256 tokenID) external returns(uint256, uint256); } /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is ERC165, IERC721 { using SafeMath for uint256; using Address for address; using Counters for Counters.Counter; struct powerNLuck { uint256 power; uint256 luck; } uint256 public totalSupply; //uint256 is tokenNo and powerNLuck is associated details in uint256 mapping (uint256 => powerNLuck) public powerNLucks; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping (address => Counters.Counter) private _ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ constructor () public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0)); return _ownedTokensCount[owner].current(); } /** * @dev Gets the owner of the specified token ID * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0)); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = ownerOf(tokenId); require(to != owner); require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId)); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != msg.sender); _operatorApprovals[msg.sender][to] = approved; emit ApprovalForAll(msg.sender, to, approved); } /** * @dev Tells whether an operator is approved by a given owner * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address * Usage of this method is discouraged, use `safeTransferFrom` whenever possible * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom(address from, address to, uint256 tokenId) public { require(_isApprovedOrOwner(msg.sender, tokenId)); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data)); } /** * @dev Returns whether the specified token exists * @param tokenId uint256 ID of the token to query the existence of * @return bool whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId, uint256 _userSeed) internal { require(to != address(0)); require(!_exists(tokenId)); require(totalSupply <= 3187, 'Excedend Max Token Supply'); _tokenOwner[tokenId] = to; _ownedTokensCount[to].increment(); totalSupply++; //generating random numbers for luck and power based on previous blockhash and user seed //this method of entropy is not very secure, but kept it as consent of client uint256 _luck = uint256(keccak256(abi.encodePacked(blockhash( block.number -1), _userSeed))) % 100; //0-99 uint256 _power = uint256(keccak256(abi.encodePacked(blockhash( block.number -10), now, _userSeed))) % 100; //0-99 //assigning lucky no and power to tokenId powerNLucks[tokenId].luck = _luck+1; //this will cause it will never be zero. powerNLucks[tokenId].power = _power+1; //this will cause it will never be zero. emit Transfer(address(0), to, tokenId); } function _mintSyncedTokens(uint256 tokenID, address user) internal { _tokenOwner[tokenID] = user; _ownedTokensCount[user].increment(); totalSupply++; //generating random numbers for luck and power based on previous blockhash and user seed //this method of entropy is not very secure, but kept it as consent of client (uint256 _power, uint256 _luck) = OldNiftymoji(0x40b16A1b6bEA856745FeDf7E0946494B895611a2).powerNLucks(tokenID); //mainnet //(uint256 _power, uint256 _luck) = OldNiftymoji(0x03f701FB8EA5441A9Bf98B65461e795931B55298).powerNLucks(tokenID); //testnet //assigning lucky no and power to tokenId powerNLucks[tokenID].luck = _luck; //this will cause it will never be zero. powerNLucks[tokenID].power = _power; //this will cause it will never be zero. emit Transfer(address(0), user, tokenID); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner); _clearApproval(tokenId); _ownedTokensCount[owner].decrement(); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from); require(to != address(0)); _clearApproval(tokenId); _ownedTokensCount[from].decrement(); _ownedTokensCount[to].increment(); _tokenOwner[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) internal returns (bool) { if (!to.isContract()) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); return (retval == _ERC721_RECEIVED); } /** * @dev Private function to clear current approval of a given token ID * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Enumerable.sol pragma solidity ^0.5.2; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Enumerable is IERC721 { //function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId); function tokenByIndex(uint256 index) public view returns (uint256); } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721Enumerable.sol pragma solidity ^0.5.2; /** * @title ERC-721 Non-Fungible Token with optional enumeration extension logic * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => uint256[]) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /* * 0x780e9d63 === * bytes4(keccak256('totalSupply()')) ^ * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ * bytes4(keccak256('tokenByIndex(uint256)')) */ /** * @dev Constructor function */ constructor () public { // register the supported interface to conform to ERC721Enumerable via ERC165 _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev Gets the token ID at a given index of the tokens list of the requested owner * @param owner address owning the tokens list to be accessed * @param index uint256 representing the index to be accessed of the requested tokens list * @return uint256 token ID at the given index of the tokens list owned by the requested address */ function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) { require(index < balanceOf(owner)); return _ownedTokens[owner][index]; } /** * @dev Gets the total amount of tokens stored by the contract * @return uint256 representing the total amount of tokens */ function totalSupplyEnum() public view returns (uint256) { return _allTokens.length; } /** * @dev Gets the token ID at a given index of all the tokens in this contract * Reverts if the index is greater or equal to the total number of tokens * @param index uint256 representing the index to be accessed of the tokens list * @return uint256 token ID at the given index of the tokens list */ function tokenByIndex(uint256 index) public view returns (uint256) { require(index < totalSupplyEnum()); return _allTokens[index]; } /** * @dev Gets the list of token IDs of the requested owner * @param owner address owning the tokens * @return uint256[] List of token IDs owned by the requested address */ function _tokensOfOwner(address owner) internal view returns (uint256[] storage) { return _ownedTokens[owner]; } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { _ownedTokensIndex[tokenId] = _ownedTokens[to].length; _ownedTokens[to].push(tokenId); } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to address the beneficiary that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { super._mint(to, tokenId,0); _addTokenToOwnerEnumeration(to, tokenId); _addTokenToAllTokensEnumeration(tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); _removeTokenFromOwnerEnumeration(owner, tokenId); // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund _ownedTokensIndex[tokenId] = 0; _removeTokenFromAllTokensEnumeration(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _ownedTokens[from].length.sub(1); uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array _ownedTokens[from].length--; // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by // lastTokenId, or just over the end of the array if the token was the last one). } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length.sub(1); uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array _allTokens.length--; _allTokensIndex[tokenId] = 0; } } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Metadata.sol pragma solidity ^0.5.2; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Metadata is IERC721 { function name() external view returns (string memory); function symbol() external view returns (string memory); function tokenURI(uint256 tokenId) external view returns (string memory); } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721Metadata.sol pragma solidity ^0.5.2; contract ERC721Metadata is ERC165, IERC721Metadata, ERC721 { // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * 0x5b5e139f === * bytes4(keccak256('name()')) ^ * bytes4(keccak256('symbol()')) ^ * bytes4(keccak256('tokenURI(uint256)')) */ /** * @dev Constructor function */ constructor (string memory name, string memory symbol) public { _name = name; _symbol = symbol; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721_METADATA); } /** * @dev Gets the token name * @return string representing the token name */ function name() external view returns (string memory) { return _name; } /** * @dev Gets the token symbol * @return string representing the token symbol */ function symbol() external view returns (string memory) { return _symbol; } /** * @dev Returns an URI for a given token ID * Throws if the token ID does not exist. May return an empty string. * @param tokenId uint256 ID of the token to query */ function tokenURI(uint256 tokenId) external view returns (string memory) { require(_exists(tokenId)); return _tokenURIs[tokenId]; } /** * @dev Internal function to set the token URI for a given token * Reverts if the token ID does not exist * @param tokenId uint256 ID of the token to set its URI * @param uri string URI to assign */ function _setTokenURI(uint256 tokenId, string memory uri) internal { require(_exists(tokenId)); _tokenURIs[tokenId] = uri; } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned by the msg.sender */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol pragma solidity ^0.5.2; /** * @title Full ERC721 Token * This implementation includes all the required and some optional functionality of the ERC721 standard * Moreover, it includes approve all functionality using operator terminology * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata { constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) { // solhint-disable-previous-line no-empty-blocks } } // File: contracts/TradeableERC721Token.sol pragma solidity ^0.5.2; contract OwnableDelegateProxy { } contract ProxyRegistry { mapping(address => OwnableDelegateProxy) public proxies; } /** * @title TradeableERC721Token * TradeableERC721Token - ERC721 contract that whitelists a trading address, and has minting functionality. */ contract TradeableERC721Token is ERC721Full, Ownable { using Strings for string; uint256 public tokenPrice=5 * (10**16) ; //price of token to buy address proxyRegistryAddress; uint256 private _currentTokenId = 0; constructor(string memory _name, string memory _symbol) ERC721Full(_name, _symbol) public { } /** * @dev Mints a token to an address with a tokenURI. * @param _to address of the future owner of the token */ function mintTo(address _to) public onlyOwner { uint256 newTokenId = _getNextTokenId(); _mint(_to, newTokenId,0); _incrementTokenId(); } function setTokenPrice(uint256 _tokenPrice) public onlyOwner returns(bool) { tokenPrice = _tokenPrice; return true; } function buyToken(uint256 _userSeed) public payable returns(bool) { uint256 paidAmount = msg.value; require(paidAmount == tokenPrice, "Invalid amount paid"); uint256 newTokenId = _getNextTokenId(); _mint(msg.sender, newTokenId,_userSeed); _incrementTokenId(); _owner.transfer(paidAmount); return true; } function batchMintToken(address[] memory _buyer) public onlyOwner returns(bool) { uint256 buyerLength = _buyer.length; require(buyerLength <= 100, "please try less then 101"); for(uint256 i=0;i<buyerLength;i++) { uint256 newTokenId = _getNextTokenId(); _mint(_buyer[i], newTokenId,0); _incrementTokenId(); } return true; } /** * @dev calculates the next token ID based on value of _currentTokenId * @return uint256 for the next token ID */ function _getNextTokenId() private view returns (uint256) { return _currentTokenId.add(1); } /** * @dev increments the value of _currentTokenId */ function _incrementTokenId() private { _currentTokenId++; } function baseTokenURI() public view returns (string memory) { return ""; } function tokenURI(uint256 _tokenId) external view returns (string memory) { return Strings.strConcat(baseTokenURI(),Strings.uint2str(_tokenId) ); } /** * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings. */ function isApprovedForAll( address owner, address operator ) public view returns (bool) { // Whitelist OpenSea proxy contract for easy trading. ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); if (address(proxyRegistry.proxies(owner)) == operator) { return true; } return super.isApprovedForAll(owner, operator); } function changeProxyURL(address newProxyAddress) public onlyOwner returns(bool){ proxyRegistryAddress = newProxyAddress; return true; } function syncFromOldContract(uint256[] memory tokens, address[] memory users) public onlyOwner returns(bool) { uint256 arrayLength = tokens.length; require(arrayLength <= 150, 'Too many tokens IDs'); //processing each entries for(uint8 i=0; i< arrayLength; i++ ){ if(!_exists(tokens[i])){ _mintSyncedTokens(tokens[i], users[i]); _incrementTokenId(); } } return true; } } // File: contracts/OpenSeaAsset.sol pragma solidity ^0.5.2; /** * @title OpenSea Asset * OpenSea Asset - A contract for easily creating custom assets on OpenSea. */ contract Niftymoji is TradeableERC721Token { string private _baseTokenURI; uint256 public changePowerPrice = 20000000000000000; //0.02 ETH uint256 public changeLuckPrice = 20000000000000000; //0.02 ETH constructor( string memory _name, string memory _symbol, string memory baseURI ) TradeableERC721Token(_name, _symbol) public { _baseTokenURI = baseURI; } function openSeaVersion() public pure returns (string memory) { return "1.2.0"; } function baseTokenURI() public view returns (string memory) { return _baseTokenURI; } function setBaseTokenURI(string memory uri) public onlyOwner { _baseTokenURI = uri; } function changePowerLuckPrice(uint256 powerPrice, uint256 luckPrice) public onlyOwner returns(bool){ changePowerPrice = powerPrice; changeLuckPrice = luckPrice; return true; } /** * Status: 0 = only power, 1 = only luck, 2 = both power and luck */ function changePowerLuck(uint256 tokenID, uint8 status) public payable returns(bool){ require(msg.sender == ownerOf(tokenID), 'This token is not owned by caller'); if(status == 0){ require(msg.value == changePowerPrice, 'Invalid ETH amount'); //generating random numbers for luck and power based on previous blockhash and timestamp //this method of entropy is not very secure, but kept it as consent of client uint256 _power = uint256(keccak256(abi.encodePacked(blockhash( block.number -10), now))) % 100; //0-99 powerNLucks[tokenID].power = _power+1; //this will cause it will never be zero. } else if(status == 1){ require(msg.value == changeLuckPrice, 'Invalid ETH amount'); uint256 _luck = uint256(keccak256(abi.encodePacked(blockhash( block.number -1)))) % 100; //0-99 powerNLucks[tokenID].luck = _luck+1; //this will cause it will never be zero. } else if(status == 2){ require(msg.value == (changePowerPrice + changeLuckPrice), 'Invalid ETH amount'); uint256 _luck = uint256(keccak256(abi.encodePacked(blockhash( block.number -1)))) % 100; //0-99 uint256 _power = uint256(keccak256(abi.encodePacked(blockhash( block.number -10), now))) % 100; //0-99 //assigning lucky no and power to tokenId powerNLucks[tokenID].luck = _luck+1; //this will cause it will never be zero. powerNLucks[tokenID].power = _power+1; //this will cause it will never be zero. } _owner.transfer(msg.value); return true; } }