Transaction Hash:
Block:
6975182 at Dec-29-2018 05:51:15 PM +UTC
Transaction Fee:
0.0008939563 ETH
$1.88
Gas Used:
288,373 Gas / 3.1 Gwei
Emitted Events:
| 55 |
HDX20.onBuyEvent( from=0xAeC539A1...5bC1af93b, tokens=530543416354412 )
|
| 56 |
HDX20.onBuyEvent( from=0x8F7C64C3...bFa45b7fB, tokens=343084742575853 )
|
| 57 |
HDX20.onBuyEvent( from=[Sender] 0x20ca0d6fe51d06946f5cc90f9f4f297d398dd6db, tokens=34485322063036785 )
|
| 58 |
EtherKnightGame.onNewRound( gRND=2, turnRound=98, eventType=131078, eventTarget=64, persoEnergy=[0, 0, 118, 118], persoDistance=[1439, 3176, 18693, 20260], powerUpSpeed=[0, 0, 0, 0], powerUpShield=[0, 0, 0, 0], blockNumberTimeout=6980942, treasureAmountFind=0, customerAddress=[Sender] 0x20ca0d6fe51d06946f5cc90f9f4f297d398dd6db )
|
| 59 |
EtherKnightGame.onBuyShare( customerAddress=[Sender] 0x20ca0d6fe51d06946f5cc90f9f4f297d398dd6db, gRND=2, perso=2, nbToken=34485322063036785, actionType=0, actionValue=0 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x20CA0D6F...D398dD6DB |
0.311240700317362423 Eth
Nonce: 2306
|
0.309346744017362423 Eth
Nonce: 2307
| 0.0018939563 | ||
|
0x829BD824...93333A830
Miner
| (F2Pool Old) | 3,204.573115073883199824 Eth | 3,204.574009030183199824 Eth | 0.0008939563 | |
| 0x8942a599...9a064F882 | 344.460933011453454714 Eth | 344.460983011453454714 Eth | 0.00005 | ||
| 0xd9Ff8cc0...D6A40387f | 3.065142369490847934 Eth | 3.066092369490847934 Eth | 0.00095 |
Execution Trace
ETH 0.001
EtherKnightGame.BuyShare( perso=2, action=0, _referrer_address=0xAeC539A116fa75E8BdcF016D3C146a25bC1af93b )
- ETH 0.00005
HDX20.buyTokenFromGame( _customerAddress=0x20CA0D6FE51d06946f5cC90F9F4f297D398dD6DB, _referrer_address=0xAeC539A116fa75E8BdcF016D3C146a25bC1af93b ) => ( 34485322063036785 )
BuyShare[EtherKnightGame (ln:722)]
CoreBuyShare[EtherKnightGame (ln:733)]get_PendingGains[EtherKnightGame (ln:754)]add[EtherKnightGame (ln:756)]mul[EtherKnightGame (ln:766)]add[EtherKnightGame (ln:768)]value[EtherKnightGame (ln:770)]mul[EtherKnightGame (ln:776)]mul[EtherKnightGame (ln:779)]mul[EtherKnightGame (ln:781)]add[EtherKnightGame (ln:783)]add[EtherKnightGame (ln:784)]add[EtherKnightGame (ln:793)]mul[EtherKnightGame (ln:798)]add[EtherKnightGame (ln:802)]mul[EtherKnightGame (ln:802)]ApplyAction[EtherKnightGame (ln:807)]mul[EtherKnightGame (ln:1019)]getSeed[EtherKnightGame (ln:1081)]blockhash[EtherKnightGame (ln:1195)]blockhash[EtherKnightGame (ln:1196)]gasleft[EtherKnightGame (ln:1203)]
actionApple[EtherKnightGame (ln:1084)]actionPowerUpShield[EtherKnightGame (ln:1085)]actionPowerUpSpeed[EtherKnightGame (ln:1086)]actionTreasure[EtherKnightGame (ln:1087)]get_modulo_value[EtherKnightGame (ln:965)]getTreasureProbabilityType[EtherKnightGame (ln:966)]get_modulo_value[EtherKnightGame (ln:913)]
actionBanana[EtherKnightGame (ln:1088)]get_modulo_value[EtherKnightGame (ln:876)]
actionAttack[EtherKnightGame (ln:1089)]get_modulo_value[EtherKnightGame (ln:1001)]apply_attack[EtherKnightGame (ln:1003)]
emitRound[EtherKnightGame (ln:1130)]onNewRound[EtherKnightGame (ln:1137)]
onBuyShare[EtherKnightGame (ln:811)]
File 1 of 2: EtherKnightGame
File 2 of 2: HDX20
/*
Introducing "ETHERKNIGHT" 3.1 our first HDX20 POWERED GAME running on the Ethereum Blockchain got a 2nd upgrade
"ETHERKNIGHT" is playable @ http://etherknightgame.io
About the game :
4 Knight Characters racing against each other to be the first to reach the goal and win the pot of gold.
How to play ETHERKNIGHT:
The Race will start after at least 1 player has bought shares of any Knight Racer then for every new item activated
a 24H countdown will reset. At the end of the countdown, the players on the first Racer will share the Treasure and
everybody else will receive their payout (no one is leaving the table without values).
In addition, when you buy shares of your favorite Racer 5% of the price will buy you HDX20 Token earning you Ethereum
from the volume of any HDX20 POWERED GAMES (visit https://hdx20.io/ for details).
Please remember, at every new buy, the price of the share is increasing a little and so will be your payout even
if you are not the winner, buying shares at the beginning of the race is highly advised.
Play for the big WIN, Play for the TREASURE, Play for staking HDX20 TOKEN or Play for all at once...Your Choice!
We wish you Good Luck!
PAYOUTS DISTRIBUTION:
.60% to the winners of the race distributed proportionally to their shares.
.25% to the community of HDX20 gamers/holders distributed as price appreciation.
.5% to developer for running, developing and expanding the platform.
.10% for provisioning the TREASURE for the next Race.
UPDATE:
we updated:
.from 1 eth played 40%(50% before) will charge the treasure, 40% (30% before) will buy shares, 5% will buy HDX20 for the player and 15% will appreciate the share price.
.adjusted the item price increase function.
This product is copyrighted. Any unauthorized copy, modification, or use without express written consent from HyperDevbox is prohibited.
Copyright 2018 HyperDevbox
*/
pragma solidity ^0.4.25;
interface HDX20Interface
{
function() payable external;
function buyTokenFromGame( address _customerAddress , address _referrer_address ) payable external returns(uint256);
function payWithToken( uint256 _eth , address _player_address ) external returns(uint256);
function appreciateTokenPrice() payable external;
function totalSupply() external view returns(uint256);
function ethBalanceOf(address _customerAddress) external view returns(uint256);
function balanceOf(address _playerAddress) external view returns(uint256);
function sellingPrice( bool includeFees) external view returns(uint256);
}
contract EtherKnightGame
{
HDX20Interface private HDXcontract = HDX20Interface(0x8942a5995bd168f347f7ec58f25a54a9a064f882);
using SafeMath for uint256;
using SafeMath128 for uint128;
/*==============================
= EVENTS =
==============================*/
event OwnershipTransferred(
address previousOwner,
address nextOwner,
uint256 timeStamp
);
event HDXcontractChanged(
address previous,
address next,
uint256 timeStamp
);
event onWithdrawGains(
address customerAddress,
uint256 ethereumWithdrawn,
uint256 timeStamp
);
event onNewRound(
uint256 gRND,
uint32 turnRound,
uint32 eventType,
uint32 eventTarget,
uint32[4] persoEnergy,
uint32[4] persoDistance,
uint32[4] powerUpSpeed,
uint32[4] powerUpShield,
uint256 blockNumberTimeout,
uint256 treasureAmountFind,
address customerAddress
);
event onNewRace(
uint256 gRND,
uint8[4] persoType,
uint256 blockNumber
);
event onBuyShare(
address customerAddress,
uint256 gRND,
uint32 perso,
uint256 nbToken,
uint32 actionType,
uint32 actionValue
);
event onMaintenance(
bool mode,
uint256 timeStamp
);
event onRefund(
address indexed customerAddress,
uint256 eth,
uint256 timeStamp
);
event onCloseEntry(
uint256 gRND
);
event onChangeBlockTimeAverage(
uint256 blocktimeavg
);
/*==============================
= MODIFIERS =
==============================*/
modifier onlyOwner
{
require (msg.sender == owner );
_;
}
modifier onlyFromHDXToken
{
require (msg.sender == address( HDXcontract ));
_;
}
modifier onlyDirectTransaction
{
require (msg.sender == tx.origin);
_;
}
modifier isPlayer
{
require (PlayerData[ msg.sender].gRND !=0);
_;
}
modifier isMaintenance
{
require (maintenanceMode==true);
_;
}
modifier isNotMaintenance
{
require (maintenanceMode==false);
_;
}
// Changing ownership of the contract safely
address public owner;
/// Contract governance.
constructor () public
{
owner = msg.sender;
if ( address(this).balance > 0)
{
owner.transfer( address(this).balance );
}
}
function changeOwner(address _nextOwner) public
onlyOwner
{
require (_nextOwner != owner);
require(_nextOwner != address(0));
emit OwnershipTransferred(owner, _nextOwner , now);
owner = _nextOwner;
}
function changeHDXcontract(address _next) public
onlyOwner
{
require (_next != address( HDXcontract ));
require( _next != address(0));
emit HDXcontractChanged(address(HDXcontract), _next , now);
HDXcontract = HDX20Interface( _next);
}
function changeBlockTimeAverage( uint256 blocktimeavg) public
onlyOwner
{
require ( blocktimeavg>0 );
blockTimeAverage = blocktimeavg;
emit onChangeBlockTimeAverage( blockTimeAverage );
}
function enableMaintenance() public
onlyOwner
{
maintenanceMode = true;
emit onMaintenance( maintenanceMode , now);
}
function disableMaintenance() public
onlyOwner
{
uint8[4] memory perso =[0,1,2,3];
maintenanceMode = false;
emit onMaintenance( maintenanceMode , now);
//reset with a new race
initRace( perso );
}
function refundMe() public
isMaintenance
{
address _playerAddress = msg.sender;
require( this_gRND>0 && GameRoundData[ this_gRND].extraData[0]>0 && GameRoundData[ this_gRND].extraData[0]<(1<<30) && PlayerData[ _playerAddress ].gRND==this_gRND);
uint256 _eth = 0;
for( uint i=0;i<4;i++)
{
_eth = _eth.add( PlayerGameRound[ _playerAddress][this_gRND].shares[i] * GameRoundData[ this_gRND].sharePrice);
PlayerGameRound[ _playerAddress][this_gRND].shares[i] = 0;
}
if (_eth>0)
{
_playerAddress.transfer( _eth );
emit onRefund( _playerAddress , _eth , now );
}
}
/*================================
= GAMES VARIABLES =
================================*/
struct PlayerData_s
{
uint256 chest;
uint256 payoutsTo;
uint256 gRND;
}
struct PlayerGameRound_s
{
uint256[4] shares;
uint128 treasure_payoutsTo;
uint128 token;
}
struct GameRoundData_s
{
uint256 blockNumber;
uint256 blockNumberTimeout;
uint256 sharePrice;
uint256[4] sharePots;
uint256 shareEthBalance;
uint256 shareSupply;
uint256 treasureSupply;
//this time we want to stream the HDX20 apprecition and dev fees on the way
uint256 allFeeSupply; //to separate the fees from the actual treasure
uint256 hdx20AppreciationPayout;
uint256 devAppreciationPayout;
//
uint256 totalTreasureFound;
uint256[6] actionBlockNumber;
uint128[4] treasurePerShare;
uint32[8] persoData; //energy[4] distance[4]
uint32[8] powerUpData; //Speed[4] Shield[4]
uint32[6] actionValue;
uint32[6] extraData;//[0]==this_TurnRound , [1]==winner , [2-5] totalPlayers
}
mapping (address => PlayerData_s) private PlayerData;
mapping (address => mapping (uint256 => PlayerGameRound_s)) private PlayerGameRound;
mapping (uint256 => GameRoundData_s) private GameRoundData;
bool private maintenanceMode=false;
uint256 private this_gRND =0;
//85 , missing 15% for shares appreciation eg:share price increase
uint8 constant private HDX20BuyFees = 5;
uint8 constant private TREASUREBuyFees = 40;
uint8 constant private BUYPercentage = 40;
//the part to keep from the treasure for next round treasure + hdx20 appreciation + dev
uint8 constant private DevFees = 5;
uint8 constant private TreasureFees = 10;
uint8 constant private AppreciationFees = 25;
uint8 constant private AddedFees = DevFees+TreasureFees+AppreciationFees;
uint256 constant internal magnitude = 1e18;
uint256 private genTreasure = 0;
uint256 constant private minimumSharePrice = 0.001 ether;
uint256 private blockTimeAverage = 15; //seconds per block
uint8[4] private this_Perso_Type;
/*================================
= PUBLIC FUNCTIONS =
================================*/
//fallback will be called only from the HDX token contract to fund the game from customers's HDX20
function()
payable
public
onlyFromHDXToken
{
}
function ChargeTreasure() public payable
{
genTreasure = SafeMath.add( genTreasure , msg.value);
}
function buyTreasureShares(GameRoundData_s storage _GameRoundData , uint256 _eth ) private
returns( uint256)
{
uint256 _nbshares = (_eth.mul( magnitude)) / _GameRoundData.sharePrice;
uint256 _nbsharesForTreasure = (_nbshares.mul( 100-DevFees-TreasureFees-AppreciationFees)) / 100;
//now we do separate for streamline payment
_GameRoundData.treasureSupply = _GameRoundData.treasureSupply.add( _nbsharesForTreasure );
//the difference is for the allFeeSupply
_GameRoundData.allFeeSupply = _GameRoundData.allFeeSupply.add( _nbshares - _nbsharesForTreasure);
_GameRoundData.shareSupply = _GameRoundData.shareSupply.add( _nbshares );
return( _nbshares);
}
function initRace( uint8[4] p ) public
onlyOwner
isNotMaintenance
{
this_gRND++;
GameRoundData_s storage _GameRoundData = GameRoundData[ this_gRND ];
for( uint i=0;i<4;i++)
{
this_Perso_Type[i] = p[i];
_GameRoundData.persoData[i] = 100;
_GameRoundData.persoData[4+i] = 25;
}
_GameRoundData.blockNumber = block.number;
_GameRoundData.blockNumberTimeout = block.number + (360*10*24*3600);
uint256 _sharePrice = 0.001 ether; // minimumSharePrice;
_GameRoundData.sharePrice = _sharePrice;
uint256 _nbshares = buyTreasureShares(_GameRoundData, genTreasure );
//convert into ETH
_nbshares = _nbshares.mul( _sharePrice ) / magnitude;
//start balance
_GameRoundData.shareEthBalance = _nbshares;
genTreasure = genTreasure.sub( _nbshares);
emit onNewRace( this_gRND , p , block.number);
}
function get_TotalPayout( GameRoundData_s storage _GameRoundData ) private view
returns( uint256)
{
uint256 _payout = 0;
uint256 _sharePrice = _GameRoundData.sharePrice;
for(uint i=0;i<4;i++)
{
uint256 _bet = _GameRoundData.sharePots[i];
_payout = _payout.add( _bet.mul (_sharePrice) / magnitude );
}
//from the whole treasure now since new version
uint256 _potValue = (_GameRoundData.treasureSupply.mul( _sharePrice )) / magnitude;
_payout = _payout.add( _potValue ).add(_GameRoundData.totalTreasureFound );
return( _payout );
}
function get_PendingGains( address _player_address , uint256 _gRND) private view
returns( uint256)
{
//did not play
if (PlayerData[ _player_address].gRND != _gRND || _gRND==0) return( 0 );
GameRoundData_s storage _GameRoundData = GameRoundData[ _gRND ];
uint32 _winner = _GameRoundData.extraData[1];
uint256 _gains = 0;
uint256 _treasure = 0;
uint256 _sharePrice = _GameRoundData.sharePrice;
uint256 _shares;
PlayerGameRound_s storage _PlayerGameRound = PlayerGameRound[ _player_address][_gRND];
for(uint i=0;i<4;i++)
{
_shares = _PlayerGameRound.shares[ i ];
_gains = _gains.add( _shares.mul( _sharePrice) / magnitude );
_treasure = _treasure.add(_shares.mul( _GameRoundData.treasurePerShare[ i ] ) / magnitude);
}
if (_treasure >= _PlayerGameRound.treasure_payoutsTo) _treasure = _treasure.sub(_PlayerGameRound.treasure_payoutsTo );
else _treasure = 0;
_gains = _gains.add(_treasure );
//if the race payment is made (race is over) then we add also the winner prize
if (_winner>0 && _GameRoundData.extraData[0] >= (1<<30))
{
_shares = _PlayerGameRound.shares[ _winner-1 ];
if (_shares>0)
{
//from the whole treasure now since new version
_treasure = (_GameRoundData.treasureSupply.mul( _sharePrice )) / magnitude;
_gains = _gains.add( _treasure.mul( _shares ) / _GameRoundData.sharePots[ _winner-1] );
}
}
return( _gains );
}
//only for the Result Data Screen on the game not used for the payout
function get_PendingGainsAll( address _player_address , uint256 _gRND) private view
returns( uint256)
{
//did not play
if (PlayerData[ _player_address].gRND != _gRND || _gRND==0) return( 0 );
GameRoundData_s storage _GameRoundData = GameRoundData[ _gRND ];
uint32 _winner = _GameRoundData.extraData[1];
uint256 _gains = 0;
uint256 _treasure = 0;
uint256 _sharePrice = _GameRoundData.sharePrice;
uint256 _shares;
PlayerGameRound_s storage _PlayerGameRound = PlayerGameRound[ _player_address][_gRND];
for(uint i=0;i<4;i++)
{
_shares = _PlayerGameRound.shares[ i ];
_gains = _gains.add( _shares.mul( _sharePrice) / magnitude );
_treasure = _treasure.add(_shares.mul( _GameRoundData.treasurePerShare[ i ] ) / magnitude);
}
if (_treasure >= _PlayerGameRound.treasure_payoutsTo) _treasure = _treasure.sub(_PlayerGameRound.treasure_payoutsTo );
else _treasure = 0;
_gains = _gains.add(_treasure );
if (_winner>0)
{
_shares = _PlayerGameRound.shares[ _winner-1 ];
if (_shares>0)
{
//from the whole treasure now since new version
_treasure = (_GameRoundData.treasureSupply.mul( _sharePrice )) / magnitude;
_gains = _gains.add( _treasure.mul( _shares ) / _GameRoundData.sharePots[ _winner-1] );
}
}
return( _gains );
}
//process streaming HDX20 appreciation and dev fees appreciation
function process_sub_Taxes( GameRoundData_s storage _GameRoundData , uint256 minimum) private
{
uint256 _sharePrice = _GameRoundData.sharePrice;
uint256 _potValue = _GameRoundData.allFeeSupply.mul( _sharePrice ) / magnitude;
uint256 _appreciation = SafeMath.mul( _potValue , AppreciationFees) / AddedFees;
uint256 _dev = SafeMath.mul( _potValue , DevFees) / AddedFees;
if (_dev > _GameRoundData.devAppreciationPayout)
{
_dev -= _GameRoundData.devAppreciationPayout;
if (_dev>minimum)
{
_GameRoundData.devAppreciationPayout = _GameRoundData.devAppreciationPayout.add( _dev );
HDXcontract.buyTokenFromGame.value( _dev )( owner , address(0));
}
}
if (_appreciation> _GameRoundData.hdx20AppreciationPayout)
{
_appreciation -= _GameRoundData.hdx20AppreciationPayout;
if (_appreciation>minimum)
{
_GameRoundData.hdx20AppreciationPayout = _GameRoundData.hdx20AppreciationPayout.add( _appreciation );
HDXcontract.appreciateTokenPrice.value( _appreciation )();
}
}
}
//process the fees, hdx20 appreciation, calcul results at the end of the race
function process_Taxes( GameRoundData_s storage _GameRoundData ) private
{
uint32 turnround = _GameRoundData.extraData[0];
if (turnround>0 && turnround<(1<<30))
{
_GameRoundData.extraData[0] = turnround | (1<<30);
uint256 _sharePrice = _GameRoundData.sharePrice;
uint256 _potValue = _GameRoundData.allFeeSupply.mul( _sharePrice ) / magnitude;
uint256 _treasure = SafeMath.mul( _potValue , TreasureFees) / AddedFees;
genTreasure = genTreasure.add( _treasure );
//take care of any left over
process_sub_Taxes( _GameRoundData , 0);
}
}
function BuyShareWithDividends( uint32 perso , uint256 eth , uint32 action, address _referrer_address ) public
onlyDirectTransaction
{
require( maintenanceMode==false && this_gRND>0 && (eth>=minimumSharePrice) && (eth <=100 ether) && perso<=3 && action <=5 && block.number <GameRoundData[ this_gRND ].blockNumberTimeout );
address _customer_address = msg.sender;
eth = HDXcontract.payWithToken( eth , _customer_address );
require( eth>0 );
CoreBuyShare( _customer_address , perso , eth , action , _referrer_address );
}
function BuyShare( uint32 perso , uint32 action , address _referrer_address ) public payable
onlyDirectTransaction
{
address _customer_address = msg.sender;
uint256 eth = msg.value;
require( maintenanceMode==false && this_gRND>0 && (eth>=minimumSharePrice) &&(eth <=100 ether) && perso<=3 && action <=5 && block.number <GameRoundData[ this_gRND ].blockNumberTimeout);
CoreBuyShare( _customer_address , perso , eth , action , _referrer_address);
}
/*================================
= CORE BUY FUNCTIONS =
================================*/
function CoreBuyShare( address _player_address , uint32 perso , uint256 eth , uint32 action , address _referrer_address ) private
{
PlayerGameRound_s storage _PlayerGameRound = PlayerGameRound[ _player_address][ this_gRND];
GameRoundData_s storage _GameRoundData = GameRoundData[ this_gRND ];
if (PlayerData[ _player_address].gRND != this_gRND)
{
if (PlayerData[_player_address].gRND !=0)
{
uint256 _gains = get_PendingGains( _player_address , PlayerData[ _player_address].gRND );
PlayerData[ _player_address].chest = PlayerData[ _player_address].chest.add( _gains);
}
PlayerData[ _player_address ].gRND = this_gRND;
}
//HDX20BuyFees
uint256 _tempo = (eth.mul(HDX20BuyFees)) / 100;
_GameRoundData.shareEthBalance = _GameRoundData.shareEthBalance.add( eth-_tempo ); //minus the hdx20 fees
uint256 _nb_token = HDXcontract.buyTokenFromGame.value( _tempo )( _player_address , _referrer_address);
//keep track for result UI screen how many token bought in this game round
_PlayerGameRound.token += uint128(_nb_token);
//increase the treasure shares
buyTreasureShares(_GameRoundData , (eth.mul(TREASUREBuyFees)) / 100 );
//what is left for the player
eth = eth.mul( BUYPercentage) / 100;
uint256 _nbshare = (eth.mul( magnitude)) / _GameRoundData.sharePrice;
_GameRoundData.shareSupply = _GameRoundData.shareSupply.add( _nbshare );
_GameRoundData.sharePots[ perso ] = _GameRoundData.sharePots[ perso ].add( _nbshare);
_tempo = _PlayerGameRound.shares[ perso ];
if (_tempo==0)
{
_GameRoundData.extraData[ 2+perso ]++;
}
_PlayerGameRound.shares[ perso ] = _tempo.add( _nbshare);
//this will always raise the price after 1 share
if (_GameRoundData.shareSupply>magnitude)
{
_GameRoundData.sharePrice = (_GameRoundData.shareEthBalance.mul( magnitude)) / _GameRoundData.shareSupply;
}
_PlayerGameRound.treasure_payoutsTo = _PlayerGameRound.treasure_payoutsTo.add( uint128(_nbshare.mul( _GameRoundData.treasurePerShare[ perso ] ) / magnitude) );
//HDX20 streaming appreciation
process_sub_Taxes( _GameRoundData , 0.2 ether);
uint32 actionValue = ApplyAction( perso , action , _nbshare , _player_address);
_GameRoundData.actionValue[ action] = actionValue;
emit onBuyShare( _player_address , this_gRND , perso , _nb_token , action, actionValue );
}
struct GameVar_s
{
uint32[4] perso_energy;
uint32[4] perso_distance;
uint32[4] powerUpShield;
uint32[4] powerUpSpeed;
uint32 event_type;
uint32 event_target;
uint32 winner;
uint256 this_gRND;
uint256 treasureAmountFind;
bytes32 seed;
uint256 blockNumberTimeout;
uint32 turnround;
}
function actionPowerUpShield( uint32 perso , GameVar_s gamevar) pure private
{
gamevar.powerUpShield[ perso ] = 100;
}
function actionPowerUpSpeed( uint32 perso , GameVar_s gamevar) pure private
{
gamevar.powerUpSpeed[ perso ] = 100;
}
function actionApple( uint32 perso , GameVar_s gamevar) pure private
{
gamevar.event_type = 6; //apple / banana etc...
gamevar.event_target = 1<<(perso*3);
gamevar.perso_energy[ perso ] += 20;
if (gamevar.perso_energy[ perso] > 150) gamevar.perso_energy[ perso ] = 150;
}
function actionBanana( GameVar_s gamevar ) pure private
{
gamevar.event_type = 6; //apple / banana etc...
uint32 result = 2;
uint32 target = get_modulo_value(gamevar.seed,18, 4);
if (gamevar.winner>0) target = gamevar.winner-1;
uint32 shield = uint32(gamevar.powerUpShield[ target ]);
if (shield>20) result = 5; //jumping banana
else
{
uint32 dd = 4 * (101 - shield);
if (gamevar.perso_distance[ target ]>=dd) gamevar.perso_distance[ target ] -= dd;
else gamevar.perso_distance[ target ] = 0;
}
gamevar.event_target = result<<(target*3);
}
function getTreasureProbabilityType( bytes32 seed ) private pure
returns( uint32 )
{
uint8[22] memory this_TreasureProbability =[
1,1,1,1,1,1,1,1,1,1,1,1, //12 chances to have 10%
2,2,2,2,2,2, //6 chances to have 15%
3,3,3, //3 chances to have 20%
4 //1 chance to have 25%
];
return( this_TreasureProbability[ get_modulo_value(seed,24, 22) ] );
}
function distribute_treasure( uint32 type2 , uint32 target , GameVar_s gamevar) private
{
uint8[5] memory this_TreasureValue =[
1,
10,
15,
20,
25
];
//from the whole treasure now since new version
uint256 _treasureSupply = GameRoundData[ gamevar.this_gRND].treasureSupply;
uint256 _sharePrice = GameRoundData[ gamevar.this_gRND].sharePrice;
uint256 _shareSupply = GameRoundData[ gamevar.this_gRND].shareSupply;
//how many shares to sell
uint256 _amount = _treasureSupply.mul(this_TreasureValue[ type2 ] ) / 100;
GameRoundData[ gamevar.this_gRND].treasureSupply = _treasureSupply.sub( _amount );
GameRoundData[ gamevar.this_gRND].shareSupply = _shareSupply.sub( _amount );
//in eth
_amount = _amount.mul( _sharePrice ) / magnitude;
//price of shares should not change
GameRoundData[ gamevar.this_gRND].shareEthBalance = GameRoundData[ gamevar.this_gRND].shareEthBalance.sub( _amount );
gamevar.treasureAmountFind = _amount;
GameRoundData[ gamevar.this_gRND].totalTreasureFound = GameRoundData[ gamevar.this_gRND].totalTreasureFound.add( _amount );
uint256 _shares = GameRoundData[ gamevar.this_gRND].sharePots[ target ];
if (_shares>0)
{
GameRoundData[ gamevar.this_gRND].treasurePerShare[ target ] = GameRoundData[ gamevar.this_gRND].treasurePerShare[ target ].add( uint128(((_amount.mul(magnitude)) / _shares)));
}
}
function actionTreasure( uint32 perso, GameVar_s gamevar ) private
{
gamevar.event_target = get_modulo_value(gamevar.seed,18, 14);
gamevar.event_type = getTreasureProbabilityType( gamevar.seed );
if (gamevar.event_target==perso)
{
distribute_treasure( gamevar.event_type , gamevar.event_target, gamevar);
}
}
function apply_attack( uint32 perso, uint32 target , GameVar_s gamevar) pure private
{
for(uint i=0;i<4;i++)
{
uint32 damage = (1+(target % 3)) * 10;
uint32 shield = uint32( gamevar.powerUpShield[i] );
if (damage<= shield || i==perso) damage = 0;
else damage -= shield;
if (damage<gamevar.perso_energy[i]) gamevar.perso_energy[i] -= damage;
else gamevar.perso_energy[i] = 1; //minimum
target >>= 2;
}
}
function actionAttack( uint32 perso , GameVar_s gamevar ) pure private
{
gamevar.event_type = 5;
gamevar.event_target = get_modulo_value(gamevar.seed,24,256); //8 bits 4x2
apply_attack( perso , gamevar.event_target , gamevar);
}
function ApplyAction( uint32 perso , uint32 action , uint256 nbshare , address _player_address) private
returns( uint32)
{
uint32 actionValue = GameRoundData[ this_gRND].actionValue[ action ];
//only the last one is activating within the same block
if (block.number<= GameRoundData[ this_gRND].actionBlockNumber[ action]) return( actionValue);
GameVar_s memory gamevar;
gamevar.turnround = GameRoundData[ this_gRND ].extraData[0];
//now we introduce a new price increase for the items
nbshare = nbshare.mul(100*100);
nbshare /= (100+(gamevar.turnround/6));
nbshare /= magnitude;
nbshare += 10;
if (nbshare>5000) nbshare = 5000;
actionValue += uint32( nbshare );
uint16[6] memory actionPrice =[
1000, //apple
4000, //powerup shield
5000, //powerup speed
2000, //chest
1000, //banana action
3000 //attack
];
if (actionValue<actionPrice[action] && gamevar.turnround>0)
{
return( actionValue );
}
if (actionValue>=actionPrice[action])
{
GameRoundData[ this_gRND].actionBlockNumber[ action] = block.number;
actionValue = 0;
}
else action = 100; //this is the first action
gamevar.turnround++;
gamevar.this_gRND = this_gRND;
gamevar.winner = GameRoundData[ gamevar.this_gRND].extraData[1];
uint i;
for( i=0;i<4;i++)
{
gamevar.perso_energy[i] = GameRoundData[ gamevar.this_gRND].persoData[i];
gamevar.perso_distance[i] = GameRoundData[ gamevar.this_gRND].persoData[4+i];
gamevar.powerUpSpeed[i] = GameRoundData[ gamevar.this_gRND].powerUpData[i] / 2;
gamevar.powerUpShield[i] = GameRoundData[ gamevar.this_gRND].powerUpData[4+i] / 2;
}
//a little boost for the fist action maker
if (gamevar.turnround==1) gamevar.perso_energy[ perso ] += 5;
getSeed( gamevar);
if (action==0) actionApple( perso , gamevar );
if (action==1) actionPowerUpShield( perso , gamevar);
if (action==2) actionPowerUpSpeed( perso , gamevar );
if (action==3) actionTreasure( perso, gamevar);
if (action==4) actionBanana( gamevar);
if (action==5) actionAttack( perso , gamevar);
gamevar.event_type |= (perso<<16);
uint32 CurrentWinnerXpos = 0; //gamevar.perso_distance[0]; //this.Racers[n].perso_distance;
for( i=0; i<4;i++)
{
//tiredness
gamevar.perso_energy[ i ] *= 95;
gamevar.perso_energy[ i ] /= 100;
uint32 spd1 = (gamevar.perso_energy[ i ]*10) + (gamevar.powerUpSpeed[ i ]*10);
gamevar.perso_distance[ i ] = ( (gamevar.perso_distance[ i ]*95) + (spd1*100) )/100;
if (gamevar.perso_distance[i] > CurrentWinnerXpos)
{
CurrentWinnerXpos = gamevar.perso_distance[i];
gamevar.winner = uint8(i);
}
GameRoundData[ gamevar.this_gRND].persoData[i] = gamevar.perso_energy[i];
GameRoundData[ gamevar.this_gRND].persoData[4+i] = gamevar.perso_distance[i];
GameRoundData[ gamevar.this_gRND].powerUpData[i] = gamevar.powerUpSpeed[i];
GameRoundData[ gamevar.this_gRND].powerUpData[4+i] = gamevar.powerUpShield[i];
}
GameRoundData[ gamevar.this_gRND ].extraData[0] = gamevar.turnround;
GameRoundData[ gamevar.this_gRND].extraData[1] = 1+gamevar.winner;
gamevar.blockNumberTimeout = block.number + ((24*3600) / blockTimeAverage);
GameRoundData[ gamevar.this_gRND].blockNumberTimeout = gamevar.blockNumberTimeout;
emitRound( gamevar , _player_address);
return( actionValue );
}
function emitRound(GameVar_s gamevar , address _player_address) private
{
emit onNewRound(
gamevar.this_gRND,
gamevar.turnround,
gamevar.event_type,
gamevar.event_target,
gamevar.perso_energy,
gamevar.perso_distance,
gamevar.powerUpSpeed,
gamevar.powerUpShield,
gamevar.blockNumberTimeout,
gamevar.treasureAmountFind,
_player_address
);
}
function get_Gains(address _player_address) private view
returns( uint256)
{
uint256 _gains = PlayerData[ _player_address ].chest.add( get_PendingGains( _player_address , PlayerData[ _player_address].gRND ) );
if (_gains > PlayerData[ _player_address].payoutsTo)
{
_gains -= PlayerData[ _player_address].payoutsTo;
}
else _gains = 0;
return( _gains );
}
function WithdrawGains() public
isPlayer
{
address _customer_address = msg.sender;
uint256 _gains = get_Gains( _customer_address );
require( _gains>0);
PlayerData[ _customer_address ].payoutsTo = PlayerData[ _customer_address ].payoutsTo.add( _gains );
emit onWithdrawGains( _customer_address , _gains , now);
_customer_address.transfer( _gains );
}
function getSeed(GameVar_s gamevar) private view
{
uint256 _seed = uint256( blockhash( block.number-1) );
_seed ^= uint256( blockhash( block.number-2) );
_seed ^= uint256(block.coinbase) / now;
_seed += gamevar.perso_distance[0];
_seed += gamevar.perso_distance[1];
_seed += gamevar.perso_distance[2];
_seed += gamevar.perso_distance[3];
_seed += gasleft();
gamevar.seed = keccak256(abi.encodePacked( _seed));
}
function CloseEntry() public
onlyOwner
isNotMaintenance
{
GameRoundData_s storage _GameRoundData = GameRoundData[ this_gRND ];
process_Taxes( _GameRoundData);
emit onCloseEntry( this_gRND );
}
function get_probability( bytes32 seed , uint32 bytepos , uint32 percentage) pure private
returns( bool )
{
uint32 v = uint32(seed[bytepos]);
if (v<= ((255*percentage)/100)) return( true );
else return( false );
}
function get_modulo_value( bytes32 seed , uint32 bytepos, uint32 mod) pure private
returns( uint32 )
{
return( ((uint32(seed[ bytepos])*256)+(uint32(seed[ bytepos+1]))) % mod);
}
/*================================
= VIEW AND HELPERS FUNCTIONS =
================================*/
function view_get_Treasure() public
view
returns(uint256)
{
return( genTreasure);
}
function view_get_allFees() public
view
returns(uint256)
{
return( (GameRoundData[ this_gRND].allFeeSupply * GameRoundData[ this_gRND].sharePrice) / magnitude);
}
function view_get_gameData() public
view
returns( uint256 sharePrice, uint256[4] sharePots, uint256 shareSupply , uint256 shareEthBalance, uint128[4] treasurePerShare, uint32[4] totalPlayers , uint32[6] actionValue , uint256[4] shares , uint256 treasure_payoutsTo ,uint256 treasureSupply )
{
address _player_address = msg.sender;
sharePrice = GameRoundData[ this_gRND].sharePrice;
sharePots = GameRoundData[ this_gRND].sharePots;
shareSupply = GameRoundData[ this_gRND].shareSupply;
shareEthBalance = GameRoundData[ this_gRND].shareEthBalance;
treasurePerShare = GameRoundData[ this_gRND].treasurePerShare;
treasureSupply = GameRoundData[ this_gRND].treasureSupply;
uint32[4] memory totalPlayersm;
totalPlayersm[0] = GameRoundData[ this_gRND].extraData[2];
totalPlayersm[1] = GameRoundData[ this_gRND].extraData[3];
totalPlayersm[2] = GameRoundData[ this_gRND].extraData[4];
totalPlayersm[3] = GameRoundData[ this_gRND].extraData[5];
totalPlayers = totalPlayersm;
actionValue = GameRoundData[ this_gRND].actionValue;
shares = PlayerGameRound[_player_address][this_gRND].shares;
treasure_payoutsTo = PlayerGameRound[_player_address][this_gRND].treasure_payoutsTo;
}
function view_get_Gains()
public
view
returns( uint256 gains)
{
address _player_address = msg.sender;
uint256 _gains = PlayerData[ _player_address ].chest.add( get_PendingGains( _player_address , PlayerData[ _player_address].gRND) );
if (_gains > PlayerData[ _player_address].payoutsTo)
{
_gains -= PlayerData[ _player_address].payoutsTo;
}
else _gains = 0;
return( _gains );
}
function view_get_gameStates() public
view
returns(uint8[4] types, uint256 grnd, uint32 turnround, uint256 minimumshare , uint256 blockNumber , uint256 blockNumberTimeout, uint32[6] actionValue , uint32[8] persoData , uint32[8] powerUpData , uint256 blockNumberCurrent , uint256 blockTimeAvg)
{
return( this_Perso_Type, this_gRND , GameRoundData[ this_gRND].extraData[0] , minimumSharePrice , GameRoundData[ this_gRND].blockNumber,GameRoundData[ this_gRND].blockNumberTimeout, GameRoundData[ this_gRND].actionValue , GameRoundData[ this_gRND].persoData , GameRoundData[ this_gRND].powerUpData, block.number , blockTimeAverage /*, view_get_MyRacer()*/);
}
function view_get_ResultData() public
view
returns(uint32 TotalPlayer, uint256 TotalPayout ,uint256 MyTokenValue, uint256 MyToken, uint256 MyGains , uint256 MyTreasureFound )
{
address _player_address = msg.sender;
GameRoundData_s storage _GameRoundData = GameRoundData[ this_gRND ];
TotalPlayer = _GameRoundData.extraData[2]+_GameRoundData.extraData[3]+_GameRoundData.extraData[4]+_GameRoundData.extraData[5];
TotalPayout = get_TotalPayout( _GameRoundData );
MyToken = PlayerGameRound[ _player_address][ this_gRND].token;
MyTokenValue = MyToken * HDXcontract.sellingPrice( true );
MyTokenValue /= magnitude;
MyGains = 0;
MyTreasureFound = 0;
if (PlayerData[ _player_address].gRND == this_gRND)
{
MyGains = get_PendingGainsAll( _player_address , this_gRND ); //just here for the view function so not used for any payout
for(uint i=0;i<4;i++)
{
MyTreasureFound += PlayerGameRound[_player_address][ this_gRND].shares[ i ].mul( _GameRoundData.treasurePerShare[ i ] ) / magnitude;
}
if (MyTreasureFound >= PlayerGameRound[_player_address][this_gRND].treasure_payoutsTo) MyTreasureFound = MyTreasureFound.sub( PlayerGameRound[_player_address][this_gRND].treasure_payoutsTo );
else MyTreasureFound = 0;
}
}
function totalEthereumBalance()
public
view
returns(uint256)
{
return address(this).balance;
}
function view_get_maintenanceMode()
public
view
returns(bool)
{
return( maintenanceMode);
}
function view_get_blockNumbers()
public
view
returns( uint256 b1 , uint256 b2 )
{
return( block.number , GameRoundData[ this_gRND ].blockNumberTimeout);
}
}
library SafeMath {
function mul(uint256 a, uint256 b)
internal
pure
returns (uint256 c)
{
if (a == 0) {
return 0;
}
c = a * b;
require(c / a == b);
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 c)
{
c = a + b;
require(c >= a);
return c;
}
}
library SafeMath128 {
function mul(uint128 a, uint128 b)
internal
pure
returns (uint128 c)
{
if (a == 0) {
return 0;
}
c = a * b;
require(c / a == b);
return c;
}
function sub(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
require(b <= a);
return a - b;
}
function add(uint128 a, uint128 b)
internal
pure
returns (uint128 c)
{
c = a + b;
require(c >= a);
return c;
}
}File 2 of 2: HDX20
/*
'We are a gaming and entertainment network our blockChain launch product is HDX20 (http://hdx20.io)'
HDX20 tokens can be bought & sold on our exchange and are distributed every time someone is playing a HDX20 POWERED GAME.
With 4% IN and 4% OUT fee only, price of the HDX20 can only go up by design, cannot be dumped on holders and is fueled
by both the volume of transactions and HDX20 POWERED GAMES.
The 4 principles of the HDX20 are :
1) Buy it, its price will increase.
2) Sell it, its price will increase.
3) Transfer it, its price will increase.
4) Play our HDX20 powered games, its price will increase.
Our Blockchain SmartContract IS the market and makes sure that the HDX20 Price never fall below its current selling price
thus offering an unique CONTEXT where risk is known at all time and limited to the IN and OUT fees only.
We have designed a vault where your HDX20 value while still indexed on the Ethereum Price will appreciate automatically over time.
This product is copyrighted. Any unauthorized copy, modification, or use without express written consent from HyperDevbox is prohibited.
Copyright 2018 HyperDevbox
fees distribution:
.1% for developer / 3% for HDX20 price appreciation during BUY and SELL
.1% for developer / 1% for HDX20 price appreciation during token Transfer
*/
pragma solidity ^0.4.25;
interface HDX20Interface
{
function moveAccountIn( address _customerAddress ) payable external;
}
contract HDX20
{
using SafeMath for uint256;
//address of a future contract to move in, by default set to 0
HDX20Interface private NewHDX20Contract = HDX20Interface(0);
/*==============================
= EVENTS =
==============================*/
event OwnershipTransferred(
address indexed previousOwner,
address indexed nextOwner
);
event Transfer(
address indexed from,
address indexed to,
uint256 tokens
);
event onBuyEvent(
address from,
uint256 tokens
);
event onSellEvent(
address from,
uint256 tokens
);
event onAccountMovedOut(
address indexed from,
address to,
uint256 tokens,
uint256 eth
);
event onAccountMovedIn(
address indexed from,
address to,
uint256 tokens,
uint256 eth
);
event HDXcontractChanged(
address previous,
address next,
uint256 timeStamp
);
/*==============================
= MODIFIERS =
==============================*/
modifier onlyOwner
{
require (msg.sender == owner);
_;
}
modifier onlyFromGameWhiteListed
{
require (gameWhiteListed[ msg.sender ] == true);
_;
}
modifier onlyGameWhiteListed(address who)
{
require (gameWhiteListed[ who ] == true);
_;
}
modifier onlyTokenHolders() {
require(myTokens() > 0);
_;
}
address public owner;
/// Contract governance.
constructor () public
{
owner = msg.sender;
if ( address(this).balance > 0)
{
owner.transfer( address(this).balance );
}
}
/*==============================
= TOKEN VARIABLES =
==============================*/
string public name = "HDX20 token";
string public symbol = "HDX20";
uint8 constant public decimals = 18;
uint256 constant internal magnitude = 1e18;
uint8 constant internal referrerFee = 50; //that is 50% of the buyInFee fee
uint8 constant internal transferFee = 2; //50% for the community 50% for developer
uint8 constant internal buyInFee = 3;
uint8 constant internal sellOutFee = 3;
uint8 constant internal devFee = 1; //actually since dev is receiving fees in HDX20 exclusively, he is also taxed on the buyinfee so this not 1%
mapping(address => uint256) private tokenBalanceLedger;
uint256 private tokenSupply = 0;
uint256 private contractValue = 0;
uint256 private tokenPrice = 0.001 ether; //starting price
/*================================
= HDX20 VARIABLES =
================================*/
mapping(address => bool) private gameWhiteListed;
mapping(address => uint8) private superReferrerRate;
/*================================
= PUBLIC FUNCTIONS =
================================*/
/**
* Fallback function to process ethereum
*/
function()
payable
public
{
buyToken(address(0));
}
function changeOwner(address _nextOwner) public
onlyOwner
{
require (_nextOwner != owner);
require(_nextOwner != address(0));
emit OwnershipTransferred(owner, _nextOwner);
owner = _nextOwner;
}
function changeName(string _name) public
onlyOwner
{
name = _name;
}
function changeSymbol(string _symbol) public
onlyOwner
{
symbol = _symbol;
}
function addGame(address _contractAddress ) public
onlyOwner
{
gameWhiteListed[ _contractAddress ] = true;
}
function addSuperReferrer(address _contractAddress , uint8 extra_rate) public
onlyOwner
{
superReferrerRate[ _contractAddress ] = extra_rate;
}
function removeGame(address _contractAddress ) public
onlyOwner
{
gameWhiteListed[ _contractAddress ] = false;
}
function changeNewHDX20Contract(address _next) public
onlyOwner
{
require (_next != address( NewHDX20Contract ));
require( _next != address(0));
emit HDXcontractChanged(address(NewHDX20Contract), _next , now);
NewHDX20Contract = HDX20Interface( _next);
}
function buyTokenSub( uint256 _eth , address _customerAddress ) private
returns(uint256)
{
uint256 _nb_token = (_eth.mul( magnitude)) / tokenPrice;
tokenBalanceLedger[ _customerAddress ] = tokenBalanceLedger[ _customerAddress ].add( _nb_token);
tokenSupply = tokenSupply.add(_nb_token);
emit onBuyEvent( _customerAddress , _nb_token);
return( _nb_token );
}
function buyTokenFromGame( address _customerAddress , address _referrer_address ) public payable
onlyFromGameWhiteListed
returns(uint256)
{
uint256 _eth = msg.value;
if (_eth==0) return(0);
uint256 _devfee = (_eth.mul( devFee )) / 100;
uint256 _fee = (_eth.mul( buyInFee )) / 100;
if (_referrer_address != address(0) && _referrer_address != _customerAddress )
{
uint256 _ethReferrer = (_fee.mul(referrerFee + superReferrerRate[_referrer_address])) / 100;
buyTokenSub( _ethReferrer , _referrer_address);
//substract what is given to referrer
_fee = _fee.sub( _ethReferrer );
}
//for the developer as HDX20 token and also help to increase the price because taxed also on his own share like everybody else
buyTokenSub( (_devfee.mul(100-buyInFee)) / 100 , owner );
//finally buy for the buyer
uint256 _nb_token = buyTokenSub( _eth - _fee -_devfee , _customerAddress);
//add the value to the contract
contractValue = contractValue.add( _eth );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
return( _nb_token );
}
function buyToken( address _referrer_address ) public payable
returns(uint256)
{
uint256 _eth = msg.value;
address _customerAddress = msg.sender;
require( _eth>0);
uint256 _devfee = (_eth.mul( devFee )) / 100;
uint256 _fee = (_eth.mul( buyInFee )) / 100;
if (_referrer_address != address(0) && _referrer_address != _customerAddress )
{
uint256 _ethReferrer = (_fee.mul(referrerFee + superReferrerRate[_referrer_address])) / 100;
buyTokenSub( _ethReferrer , _referrer_address);
//substract what is given to referrer
_fee = _fee.sub( _ethReferrer );
}
//for the developer as HDX20 token and also help to increase the price because taxed also on his own share like everybody else
buyTokenSub( (_devfee.mul(100-buyInFee)) / 100 , owner );
//finally buy for the buyer
uint256 _nb_token = buyTokenSub( _eth - _fee -_devfee , _customerAddress);
//add the value to the contract
contractValue = contractValue.add( _eth );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
return( _nb_token );
}
function sellToken( uint256 _amount ) public
onlyTokenHolders
{
address _customerAddress = msg.sender;
uint256 balance = tokenBalanceLedger[ _customerAddress ];
require( _amount <= balance);
uint256 _eth = (_amount.mul( tokenPrice )) / magnitude;
uint256 _fee = (_eth.mul( sellOutFee)) / 100;
uint256 _devfee = (_eth.mul( devFee)) / 100;
tokenSupply = tokenSupply.sub( _amount );
balance = balance.sub( _amount );
tokenBalanceLedger[ _customerAddress] = balance;
//for the developer as HDX20 token and also help to increase the price because taxed also on his own share like everybody else
buyTokenSub( (_devfee.mul(100-buyInFee)) / 100 , owner );
//calculate what is really leaving the contract, basically _eth - _fee -devfee
_eth = _eth - _fee - _devfee;
contractValue = contractValue.sub( _eth );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
emit onSellEvent( _customerAddress , _amount);
//finally transfer the money
_customerAddress.transfer( _eth );
}
//there is no fee using token to play HDX20 powered games
function payWithToken( uint256 _eth , address _player_address ) public
onlyFromGameWhiteListed
returns(uint256)
{
require( _eth>0 && _eth <= ethBalanceOfNoFee(_player_address ));
address _game_contract = msg.sender;
uint256 balance = tokenBalanceLedger[ _player_address ];
uint256 _nb_token = (_eth.mul( magnitude) ) / tokenPrice;
require( _nb_token <= balance);
//confirm the ETH value
_eth = (_nb_token.mul( tokenPrice)) / magnitude;
balance = balance.sub(_nb_token);
tokenSupply = tokenSupply.sub( _nb_token);
tokenBalanceLedger[ _player_address ] = balance;
contractValue = contractValue.sub( _eth );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
//send the money to the game contract
_game_contract.transfer( _eth );
return( _eth );
}
function moveAccountOut() public
onlyTokenHolders
{
address _customerAddress = msg.sender;
require( ethBalanceOfNoFee( _customerAddress )>0 && address(NewHDX20Contract) != address(0));
uint256 balance = tokenBalanceLedger[ _customerAddress ];
uint256 _eth = (balance.mul( tokenPrice )) / magnitude;
tokenSupply = tokenSupply.sub( balance );
tokenBalanceLedger[ _customerAddress ] = 0;
contractValue = contractValue.sub( _eth );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
emit onAccountMovedOut( _customerAddress , address(NewHDX20Contract), balance , _eth );
//send the money to the new HDX20 contract which will buy on customer behalf at no fee converting eth for eth
//notice this could give more or less HDX20 however the eth value should be preserved
NewHDX20Contract.moveAccountIn.value(_eth)(_customerAddress);
}
function moveAccountIn(address _customerAddress) public
payable
onlyFromGameWhiteListed
{
uint256 _eth = msg.value;
//buy token at no fee
uint256 _nb_token = buyTokenSub( _eth , _customerAddress );
contractValue = contractValue.add( _eth );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
emit onAccountMovedIn( msg.sender, _customerAddress , _nb_token , _eth );
}
function appreciateTokenPrice() public payable
onlyFromGameWhiteListed
{
uint256 _eth = msg.value;
contractValue = contractValue.add( _eth );
//we need a minimum of 1 HDX20 before appreciation is activated
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
}
function transferSub(address _customerAddress, address _toAddress, uint256 _amountOfTokens)
private
returns(bool)
{
require( _amountOfTokens <= tokenBalanceLedger[_customerAddress] );
//actually a transfer of 0 token is valid in ERC20
if (_amountOfTokens>0)
{
{
uint256 _token_fee = (_amountOfTokens.mul( transferFee )) / 100;
_token_fee /= 2;
//now proceed the transfer
tokenBalanceLedger[ _customerAddress] = tokenBalanceLedger[ _customerAddress].sub( _amountOfTokens );
tokenBalanceLedger[ _toAddress] = tokenBalanceLedger[ _toAddress].add( _amountOfTokens - (_token_fee*2) );
//half fee in HDX20 directly credited to developer
tokenBalanceLedger[ owner ] += _token_fee;
//burning the other half of token to drive the price up
tokenSupply = tokenSupply.sub( _token_fee );
if (tokenSupply>magnitude)
{
tokenPrice = (contractValue.mul( magnitude)) / tokenSupply;
}
}
}
// fire event
emit Transfer(_customerAddress, _toAddress, _amountOfTokens);
// ERC20
return true;
}
function transfer(address _toAddress, uint256 _amountOfTokens)
public
returns(bool)
{
return( transferSub( msg.sender , _toAddress, _amountOfTokens));
}
/*================================
= VIEW AND HELPERS FUNCTIONS =
================================*/
function totalEthereumBalance()
public
view
returns(uint)
{
return address(this).balance;
}
function totalContractBalance()
public
view
returns(uint)
{
return contractValue;
}
function totalSupply()
public
view
returns(uint256)
{
return tokenSupply;
}
function myTokens()
public
view
returns(uint256)
{
address _customerAddress = msg.sender;
return balanceOf(_customerAddress);
}
function balanceOf(address _customerAddress)
view
public
returns(uint256)
{
return tokenBalanceLedger[_customerAddress];
}
function sellingPrice( bool includeFees)
view
public
returns(uint256)
{
uint256 _fee = 0;
uint256 _devfee=0;
if (includeFees)
{
_fee = (tokenPrice.mul( sellOutFee ) ) / 100;
_devfee = (tokenPrice.mul( devFee ) ) / 100;
}
return( tokenPrice - _fee - _devfee );
}
function buyingPrice( bool includeFees)
view
public
returns(uint256)
{
uint256 _fee = 0;
uint256 _devfee=0;
if (includeFees)
{
_fee = (tokenPrice.mul( buyInFee ) ) / 100;
_devfee = (tokenPrice.mul( devFee ) ) / 100;
}
return( tokenPrice + _fee + _devfee );
}
function ethBalanceOf(address _customerAddress)
view
public
returns(uint256)
{
uint256 _price = sellingPrice( true );
uint256 _balance = tokenBalanceLedger[ _customerAddress];
uint256 _value = (_balance.mul( _price )) / magnitude;
return( _value );
}
function myEthBalanceOf()
public
view
returns(uint256)
{
address _customerAddress = msg.sender;
return ethBalanceOf(_customerAddress);
}
function ethBalanceOfNoFee(address _customerAddress)
view
public
returns(uint256)
{
uint256 _price = sellingPrice( false );
uint256 _balance = tokenBalanceLedger[ _customerAddress];
uint256 _value = (_balance.mul( _price )) / magnitude;
return( _value );
}
function myEthBalanceOfNoFee()
public
view
returns(uint256)
{
address _customerAddress = msg.sender;
return ethBalanceOfNoFee(_customerAddress);
}
function checkGameListed(address _contract)
view
public
returns(bool)
{
return( gameWhiteListed[ _contract]);
}
function getSuperReferrerRate(address _customerAddress)
view
public
returns(uint8)
{
return( referrerFee+superReferrerRate[ _customerAddress]);
}
}
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b)
internal
pure
returns (uint256 c)
{
if (a == 0) {
return 0;
}
c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
require(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b)
internal
pure
returns (uint256 c)
{
c = a + b;
require(c >= a);
return c;
}
}