Transaction Hash:
Block:
7465496 at Mar-29-2019 08:23:45 PM +UTC
Transaction Fee:
0.000241565 ETH
$0.43
Gas Used:
48,313 Gas / 5 Gwei
Emitted Events:
7 |
CryptoDuel.resultDuel( duel=3372, winner=[Sender] 0x55d0f227f808de9b54e26d17749537d814a28603, sum=47520000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x2a65Aca4...135398226
Miner
| (DwarfPool) | 2,380.794861865021519864 Eth | 2,380.795103430021519864 Eth | 0.000241565 | |
0x55D0f227...814A28603 |
0.132536803184548188 Eth
Nonce: 138
|
0.179815238184548188 Eth
Nonce: 139
| 0.047278435 | ||
0x869eB8a1...25DC3E526 | 5.36851610782422588 Eth | 5.32099610782422588 Eth | 0.04752 |
Execution Trace
CryptoDuel.GetWin( _duelID=3372 )
- ETH 0.04752
0x55d0f227f808de9b54e26d17749537d814a28603.CALL( )
GetWin[CryptoDuel (ln:300)]
blockhash[CryptoDuel (ln:316)]
safePerc[CryptoDuel (ln:318)]
transfer[CryptoDuel (ln:320)]
safeSub[CryptoDuel (ln:320)]
transfer[CryptoDuel (ln:321)]
safeSub[CryptoDuel (ln:321)]
safeAdd[CryptoDuel (ln:323)]
safeMul[CryptoDuel (ln:323)]
refundDuel[CryptoDuel (ln:325)]
blockhash[CryptoDuel (ln:329)]
safeMul[CryptoDuel (ln:331)]
safePerc[CryptoDuel (ln:332)]
safeSub[CryptoDuel (ln:335)]
transfer[CryptoDuel (ln:340)]
resultDuel[CryptoDuel (ln:342)]
transfer[CryptoDuel (ln:345)]
resultDuel[CryptoDuel (ln:347)]
safeAdd[CryptoDuel (ln:353)]
safePerc[CryptoDuel (ln:353)]
safeAdd[CryptoDuel (ln:357)]
safeAdd[CryptoDuel (ln:358)]
safePerc[CryptoDuel (ln:358)]
safeSub[CryptoDuel (ln:364)]
safeAdd[CryptoDuel (ln:365)]
safePerc[CryptoDuel (ln:365)]
safeAdd[CryptoDuel (ln:366)]
safeSub[CryptoDuel (ln:366)]
safePerc[CryptoDuel (ln:366)]
safeAdd[CryptoDuel (ln:368)]
safeSub[CryptoDuel (ln:368)]
safePerc[CryptoDuel (ln:368)]
pragma solidity ^0.4.25; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ contract SafeMath { /** * @dev Subtracts two numbers, reverts on overflow. */ function safeSub(uint256 x, uint256 y) internal pure returns (uint256) { assert(y <= x); uint256 z = x - y; return z; } /** * @dev Adds two numbers, reverts on overflow. */ function safeAdd(uint256 x, uint256 y) internal pure returns (uint256) { uint256 z = x + y; assert(z >= x); return z; } /** * @dev Integer division of two numbers, reverts on division by zero. */ function safeDiv(uint256 x, uint256 y) internal pure returns (uint256) { uint256 z = x / y; return z; } /** * @dev Multiplies two numbers, reverts on overflow. */ function safeMul(uint256 x, uint256 y) internal pure returns (uint256) { if (x == 0) { return 0; } uint256 z = x * y; assert(z / x == y); return z; } /** * @dev Returns the integer percentage of the number. */ function safePerc(uint256 x, uint256 y) internal pure returns (uint256) { if (x == 0) { return 0; } uint256 z = x * y; assert(z / x == y); z = z / 10000; // percent to hundredths return z; } /** * @dev Returns the minimum value of two numbers. */ function min(uint256 x, uint256 y) internal pure returns (uint256) { uint256 z = x <= y ? x : y; return z; } /** * @dev Returns the maximum value of two numbers. */ function max(uint256 x, uint256 y) internal pure returns (uint256) { uint256 z = x >= y ? x : y; return z; } } /** * @title Ownable contract - base contract with an owner */ contract Ownable { address public owner; address public newOwner; event OwnershipTransferred(address indexed _from, address indexed _to); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { assert(msg.sender == owner); _; } /** * @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 _newOwner) public onlyOwner { assert(_newOwner != address(0)); newOwner = _newOwner; } /** * @dev Accept transferOwnership. */ function acceptOwnership() public { if (msg.sender == newOwner) { emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } } /** * @title Agent contract - base contract with an agent */ contract Agent is Ownable { address public defAgent; mapping(address => bool) public Agents; event UpdatedAgent(address _agent, bool _status); constructor() public { defAgent = msg.sender; Agents[msg.sender] = true; } modifier onlyAgent() { assert(Agents[msg.sender]); _; } function updateAgent(address _agent, bool _status) public onlyOwner { assert(_agent != address(0)); Agents[_agent] = _status; emit UpdatedAgent(_agent, _status); } } /** * @title CryptoDuel game */ contract CryptoDuel is Agent, SafeMath { uint public fee = 100; // 1% from bet uint public refGroupFee = 5000; // 50% from profit uint public refLevel1Fee = 1000; // 10% from profit uint public refLevel2Fee = 500; // 5% from profit uint public min = 1000000000000000; // 0.001 ETH uint public max = 1000000000000000000000; // 1000 ETH uint256 public start = 0; // Must be equal to the date of issue tokens uint256 public period = 30 days; // By default, the dividend accrual period is 30 days /** State * * - New: 0 * - Deleted: 1 * - OnGoing: 2 * - Closed: 3 */ enum State{New, Deleted, OnGoing, Closed} struct _duel { address creator; address responder; uint bet; uint blocknumber; int refID; State state; } _duel[] public Duels; mapping(int => address) public RefGroup; // RefGroup[id group] = address referrer mapping(address => address) public RefAddr; // RefAddr[address referal] = address referrer mapping(uint => uint) public reward; // reward[period] = amount mapping(address => uint) public rewardGroup; // rewardGroup[address] = amount mapping(address => uint) public rewardAddr; // rewardAddr[address] = amount mapping(uint => bool) public AlreadyReward; // AlreadyReward[period] = true/false event newDuel(uint duel, address indexed creator, address indexed responder, uint bet, int refID); event deleteDuel(uint duel); event respondDuel(uint duel, address indexed responder); event refundDuel(uint duel); event resultDuel(uint duel, address indexed winner, uint sum); event changeMin(uint min); event changeMax(uint max); event changeRefGroup(int ID, address referrer); event changeRefAddr(address referal, address referrer); event changeFee(uint fee); event changeRefGroupFee(uint refGroupFee); event changeRefLevel1Fee(uint refLevel1Fee); event changeRefLevel2Fee(uint refLevel2Fee); event withdrawProfit(uint fee, address RefGroup); event UpdatedPeriod(uint _period); constructor() public { RefGroup[0] = msg.sender; emit changeRefGroup(0, msg.sender); } function CreateDuel(address _responder) payable external { require(msg.value >= min && msg.value <= max); Duels.push(_duel({ creator : msg.sender, responder : _responder, bet : msg.value, blocknumber : 0, state : State.New, refID : 0 })); emit newDuel(Duels.length - 1, msg.sender, _responder, msg.value, 0); } function CreateDuel(address _responder, int _refID) payable external { require(msg.value >= min && msg.value <= max); require(RefGroup[_refID] != address(0)); Duels.push(_duel({ creator : msg.sender, responder : _responder, bet : msg.value, blocknumber : 0, state : State.New, refID : _refID })); emit newDuel(Duels.length - 1, msg.sender, _responder, msg.value, _refID); } function RespondDuel(uint _duelID) payable external { _duel storage duel = Duels[_duelID]; require(duel.state == State.New); require(duel.bet == msg.value); require(duel.responder == msg.sender || duel.responder == address(0)); duel.state = State.OnGoing; duel.responder = msg.sender; duel.blocknumber = block.number; emit respondDuel(_duelID, msg.sender); } function DeleteDuel(uint _duelID) external { _duel storage duel = Duels[_duelID]; require(duel.creator == msg.sender); require(duel.state == State.New); duel.state = State.Deleted; uint duel_fee = safePerc(duel.bet, fee); uint256 N = 1; if (block.timestamp > start) { N = (block.timestamp - start) / period + 1; } reward[N] = safeAdd(reward[N], duel_fee); duel.creator.transfer(safeSub(duel.bet, duel_fee)); emit deleteDuel(_duelID); } function GetWin(uint _duelID) external { _duel storage duel = Duels[_duelID]; require(duel.state == State.OnGoing); require(duel.creator == msg.sender || duel.responder == msg.sender); require(block.number > duel.blocknumber + 1); duel.state = State.Closed; uint duel_fee = 0; uint256 N = 1; if (block.timestamp > start) { N = (block.timestamp - start) / period + 1; } if (blockhash(duel.blocknumber) == 0 || (block.number - duel.blocknumber) > 256) { duel_fee = safePerc(duel.bet, fee); duel.creator.transfer(safeSub(duel.bet, duel_fee)); duel.responder.transfer(safeSub(duel.bet, duel_fee)); reward[N] = safeAdd(reward[N], safeMul(2, duel_fee)); emit refundDuel(_duelID); } else { uint hash = uint(keccak256(abi.encodePacked(blockhash(duel.blocknumber + 1), duel.creator, duel.responder, duel.bet))); uint duel_bet_common = safeMul(2, duel.bet); duel_fee = safePerc(duel_bet_common, fee); uint refFee = 0; uint sum = safeSub(duel_bet_common, duel_fee); address winner; if (hash % 2 == 0) { duel.creator.transfer(sum); winner = duel.creator; emit resultDuel(_duelID, duel.creator, sum); } else { duel.responder.transfer(sum); winner = duel.responder; emit resultDuel(_duelID, duel.responder, sum); } // ref level 1 if (RefAddr[winner] != address(0)) { refFee = refLevel1Fee; rewardAddr[RefAddr[winner]] = safeAdd(rewardAddr[RefAddr[winner]], safePerc(duel_fee, refLevel1Fee)); // ref level 2 if (RefAddr[RefAddr[winner]] != address(0)) { refFee = safeAdd(refFee, refLevel2Fee); rewardAddr[RefAddr[RefAddr[winner]]] = safeAdd(rewardAddr[RefAddr[RefAddr[winner]]], safePerc(duel_fee, refLevel2Fee)); } } // ref group if (duel.refID != 0) { refFee = safeSub(refGroupFee, refFee); rewardGroup[RefGroup[duel.refID]] = safeAdd(rewardGroup[RefGroup[duel.refID]], safePerc(duel_fee, refFee)); reward[N] = safeAdd(reward[N], safeSub(duel_fee, safePerc(duel_fee, refGroupFee))); } else { reward[N] = safeAdd(reward[N], safeSub(duel_fee, safePerc(duel_fee, refFee))); } } } function setMin(uint _min) external onlyOwner { min = _min; emit changeMin(_min); } function setMax(uint _max) external onlyOwner { max = _max; emit changeMax(_max); } function setFee(uint _fee) external onlyOwner { fee = _fee; emit changeFee(_fee); } function setRefGroupFee(uint _refGroupFee) external onlyOwner { refGroupFee = _refGroupFee; emit changeRefGroupFee(_refGroupFee); } function setRefLevel1Fee(uint _refLevel1Fee) external onlyOwner { refLevel1Fee = _refLevel1Fee; emit changeRefLevel1Fee(_refLevel1Fee); } function setRefLevel2Fee(uint _refLevel2Fee) external onlyOwner { refLevel2Fee = _refLevel2Fee; emit changeRefLevel2Fee(_refLevel2Fee); } function setRefGroup(int _ID, address _referrer) external onlyAgent { RefGroup[_ID] = _referrer; emit changeRefGroup(_ID, _referrer); } function setRefAddr(address _referral, address _referrer) external onlyAgent { RefAddr[_referral] = _referrer; emit changeRefAddr(_referral, _referrer); } function withdraw() external onlyOwner returns (bool success) { uint256 N = 1; if (block.timestamp > start) { N = (block.timestamp - start) / period; } if (!AlreadyReward[N]) { uint amount = reward[N]; AlreadyReward[N] = true; msg.sender.transfer(amount); emit withdrawProfit(amount, msg.sender); return true; } else { return false; } } function withdrawRefGroup() external returns (bool success) { require(rewardGroup[msg.sender] > 0); uint amount = rewardGroup[msg.sender]; rewardGroup[msg.sender] = 0; msg.sender.transfer(amount); emit withdrawProfit(amount, msg.sender); return true; } function withdrawRefAddr() external returns (bool success) { require(rewardAddr[msg.sender] > 0); uint amount = rewardAddr[msg.sender]; rewardAddr[msg.sender] = 0; msg.sender.transfer(amount); emit withdrawProfit(amount, msg.sender); return true; } function withdrawRefBoth() external returns (bool success) { require(rewardAddr[msg.sender] > 0 || rewardGroup[msg.sender] > 0); uint amount = safeAdd(rewardAddr[msg.sender], rewardGroup[msg.sender]); rewardAddr[msg.sender] = 0; rewardGroup[msg.sender] = 0; msg.sender.transfer(amount); emit withdrawProfit(amount, msg.sender); return true; } /** * Owner can change period */ function setPeriod(uint _period) external onlyOwner { period = _period; emit UpdatedPeriod(_period); } /** * Owner can change start */ function setStart(uint _start) external onlyOwner { start = _start; } }