Dicether contract has migrated to a new address.
More Info
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
GameChannel
Compiler Version
v0.5.0+commit.1d4f565a
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-02-06 */ pragma solidity ^0.5.0; interface ConflictResolutionInterface { function minHouseStake(uint activeGames) external view returns(uint); function maxBalance() external view returns(int); function conflictEndFine() external pure returns(int); function isValidBet(uint8 _gameType, uint _betNum, uint _betValue) external view returns(bool); function endGameConflict( uint8 _gameType, uint _betNum, uint _betValue, int _balance, uint _stake, bytes32 _serverSeed, bytes32 _userSeed ) external view returns(int); function serverForceGameEnd( uint8 gameType, uint _betNum, uint _betValue, int _balance, uint _stake, bytes32 _serverSeed, bytes32 _userSeed, uint _endInitiatedTime ) external view returns(int); function userForceGameEnd( uint8 _gameType, uint _betNum, uint _betValue, int _balance, uint _stake, uint _endInitiatedTime ) external view returns(int); } library MathUtil { /** * @dev Returns the absolute value of _val. * @param _val value * @return The absolute value of _val. */ function abs(int _val) internal pure returns(uint) { if (_val < 0) { return uint(-_val); } else { return uint(_val); } } /** * @dev Calculate maximum. */ function max(uint _val1, uint _val2) internal pure returns(uint) { return _val1 >= _val2 ? _val1 : _val2; } /** * @dev Calculate minimum. */ function min(uint _val1, uint _val2) internal pure returns(uint) { return _val1 <= _val2 ? _val1 : _val2; } } contract Ownable { address payable public owner; address payable public pendingOwner; event LogOwnerShipTransferred(address indexed previousOwner, address indexed newOwner); event LogOwnerShipTransferInitiated(address indexed previousOwner, address indexed newOwner); /** * @dev Modifier, which throws if called by other account than owner. */ modifier onlyOwner { require(msg.sender == owner); _; } /** * @dev Modifier throws if called by any account other than the pendingOwner. */ modifier onlyPendingOwner() { require(msg.sender == pendingOwner); _; } /** * @dev Set contract creator as initial owner */ constructor() public { owner = msg.sender; pendingOwner = address(0); } /** * @dev Allows the current owner to set the pendingOwner address. * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address payable _newOwner) public onlyOwner { pendingOwner = _newOwner; emit LogOwnerShipTransferInitiated(owner, _newOwner); } /** * @dev PendingOwner can accept ownership. */ function claimOwnership() public onlyPendingOwner { owner = pendingOwner; pendingOwner = address(0); emit LogOwnerShipTransferred(owner, pendingOwner); } } contract Activatable is Ownable { bool public activated = false; /// @dev Event is fired if activated. event LogActive(); /// @dev Modifier, which only allows function execution if activated. modifier onlyActivated() { require(activated); _; } /// @dev Modifier, which only allows function execution if not activated. modifier onlyNotActivated() { require(!activated); _; } /// @dev activate contract, can be only called once by the contract owner. function activate() public onlyOwner onlyNotActivated { activated = true; emit LogActive(); } } contract ConflictResolutionManager is Ownable { /// @dev Conflict resolution contract. ConflictResolutionInterface public conflictRes; /// @dev New Conflict resolution contract. address public newConflictRes = address(0); /// @dev Time update of new conflict resolution contract was initiated. uint public updateTime = 0; /// @dev Min time before new conflict res contract can be activated after initiating update. uint public constant MIN_TIMEOUT = 3 days; /// @dev Min time before new conflict res contract can be activated after initiating update. uint public constant MAX_TIMEOUT = 6 days; /// @dev Update of conflict resolution contract was initiated. event LogUpdatingConflictResolution(address newConflictResolutionAddress); /// @dev New conflict resolution contract is active. event LogUpdatedConflictResolution(address newConflictResolutionAddress); /** * @dev Constructor * @param _conflictResAddress conflict resolution contract address. */ constructor(address _conflictResAddress) public { conflictRes = ConflictResolutionInterface(_conflictResAddress); } /** * @dev Initiate conflict resolution contract update. * @param _newConflictResAddress New conflict resolution contract address. */ function updateConflictResolution(address _newConflictResAddress) public onlyOwner { newConflictRes = _newConflictResAddress; updateTime = block.timestamp; emit LogUpdatingConflictResolution(_newConflictResAddress); } /** * @dev Active new conflict resolution contract. */ function activateConflictResolution() public onlyOwner { require(newConflictRes != address(0)); require(updateTime != 0); require(updateTime + MIN_TIMEOUT <= block.timestamp && block.timestamp <= updateTime + MAX_TIMEOUT); conflictRes = ConflictResolutionInterface(newConflictRes); newConflictRes = address(0); updateTime = 0; emit LogUpdatedConflictResolution(newConflictRes); } } contract Pausable is Activatable { using SafeMath for uint; /// @dev Is contract paused. Initial it is paused. bool public paused = true; /// @dev Time pause was called uint public timePaused = block.timestamp; /// @dev Modifier, which only allows function execution if not paused. modifier onlyNotPaused() { require(!paused, "paused"); _; } /// @dev Modifier, which only allows function execution if paused. modifier onlyPaused() { require(paused); _; } /// @dev Modifier, which only allows function execution if paused longer than timeSpan. modifier onlyPausedSince(uint timeSpan) { require(paused && (timePaused.add(timeSpan) <= block.timestamp)); _; } /// @dev Event is fired if paused. event LogPause(); /// @dev Event is fired if pause is ended. event LogUnpause(); /** * @dev Pause contract. No new game sessions can be created. */ function pause() public onlyOwner onlyNotPaused { paused = true; timePaused = block.timestamp; emit LogPause(); } /** * @dev Unpause contract. Initial contract is paused and can only be unpaused after activating it. */ function unpause() public onlyOwner onlyPaused onlyActivated { paused = false; timePaused = 0; emit LogUnpause(); } } contract Destroyable is Pausable { /// @dev After pausing the contract for 20 days owner can selfdestruct it. uint public constant TIMEOUT_DESTROY = 20 days; /** * @dev Destroy contract and transfer ether to owner. */ function destroy() public onlyOwner onlyPausedSince(TIMEOUT_DESTROY) { selfdestruct(owner); } } contract GameChannelBase is Destroyable, ConflictResolutionManager { using SafeCast for int; using SafeCast for uint; using SafeMath for int; using SafeMath for uint; /// @dev Different game session states. enum GameStatus { ENDED, ///< @dev Game session is ended. ACTIVE, ///< @dev Game session is active. USER_INITIATED_END, ///< @dev User initiated non regular end. SERVER_INITIATED_END ///< @dev Server initiated non regular end. } /// @dev Reason game session ended. enum ReasonEnded { REGULAR_ENDED, ///< @dev Game session is regularly ended. SERVER_FORCED_END, ///< @dev User did not respond. Server forced end. USER_FORCED_END, ///< @dev Server did not respond. User forced end. CONFLICT_ENDED ///< @dev Server or user raised conflict ans pushed game state, opponent pushed same game state. } struct Game { /// @dev Game session status. GameStatus status; /// @dev User's stake. uint128 stake; /// @dev Last game round info if not regularly ended. /// If game session is ended normally this data is not used. uint8 gameType; uint32 roundId; uint betNum; uint betValue; int balance; bytes32 userSeed; bytes32 serverSeed; uint endInitiatedTime; } /// @dev Minimal time span between profit transfer. uint public constant MIN_TRANSFER_TIMESPAN = 1 days; /// @dev Maximal time span between profit transfer. uint public constant MAX_TRANSFER_TIMSPAN = 6 * 30 days; bytes32 public constant EIP712DOMAIN_TYPEHASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); bytes32 public constant BET_TYPEHASH = keccak256( "Bet(uint32 roundId,uint8 gameType,uint256 number,uint256 value,int256 balance,bytes32 serverHash,bytes32 userHash,uint256 gameId)" ); bytes32 public DOMAIN_SEPERATOR; /// @dev Current active game sessions. uint public activeGames = 0; /// @dev Game session id counter. Points to next free game session slot. So gameIdCntr -1 is the // number of game sessions created. uint public gameIdCntr = 1; /// @dev Only this address can accept and end games. address public serverAddress; /// @dev Address to transfer profit to. address payable public houseAddress; /// @dev Current house stake. uint public houseStake = 0; /// @dev House profit since last profit transfer. int public houseProfit = 0; /// @dev Min value user needs to deposit for creating game session. uint128 public minStake; /// @dev Max value user can deposit for creating game session. uint128 public maxStake; /// @dev Timeout until next profit transfer is allowed. uint public profitTransferTimeSpan = 14 days; /// @dev Last time profit transferred to house. uint public lastProfitTransferTimestamp; /// @dev Maps gameId to game struct. mapping (uint => Game) public gameIdGame; /// @dev Maps user address to current user game id. mapping (address => uint) public userGameId; /// @dev Maps user address to pending returns. mapping (address => uint) public pendingReturns; /// @dev Modifier, which only allows to execute if house stake is high enough. modifier onlyValidHouseStake(uint _activeGames) { uint minHouseStake = conflictRes.minHouseStake(_activeGames); require(houseStake >= minHouseStake, "inv houseStake"); _; } /// @dev Modifier to check if value send fulfills user stake requirements. modifier onlyValidValue() { require(minStake <= msg.value && msg.value <= maxStake, "inv stake"); _; } /// @dev Modifier, which only allows server to call function. modifier onlyServer() { require(msg.sender == serverAddress); _; } /// @dev Modifier, which only allows to set valid transfer timeouts. modifier onlyValidTransferTimeSpan(uint transferTimeout) { require(transferTimeout >= MIN_TRANSFER_TIMESPAN && transferTimeout <= MAX_TRANSFER_TIMSPAN); _; } /// @dev This event is fired when user creates game session. event LogGameCreated(address indexed user, uint indexed gameId, uint128 stake, bytes32 indexed serverEndHash, bytes32 userEndHash); /// @dev This event is fired when user requests conflict end. event LogUserRequestedEnd(address indexed user, uint indexed gameId); /// @dev This event is fired when server requests conflict end. event LogServerRequestedEnd(address indexed user, uint indexed gameId); /// @dev This event is fired when game session is ended. event LogGameEnded(address indexed user, uint indexed gameId, uint32 roundId, int balance, ReasonEnded reason); /// @dev this event is fired when owner modifies user's stake limits. event LogStakeLimitsModified(uint minStake, uint maxStake); /** * @dev Contract constructor. * @param _serverAddress Server address. * @param _minStake Min value user needs to deposit to create game session. * @param _maxStake Max value user can deposit to create game session. * @param _conflictResAddress Conflict resolution contract address. * @param _houseAddress House address to move profit to. * @param _chainId Chain id for signature domain. */ constructor( address _serverAddress, uint128 _minStake, uint128 _maxStake, address _conflictResAddress, address payable _houseAddress, uint _chainId ) public ConflictResolutionManager(_conflictResAddress) { require(_minStake > 0 && _minStake <= _maxStake); serverAddress = _serverAddress; houseAddress = _houseAddress; lastProfitTransferTimestamp = block.timestamp; minStake = _minStake; maxStake = _maxStake; DOMAIN_SEPERATOR = keccak256(abi.encode( EIP712DOMAIN_TYPEHASH, keccak256("Dicether"), keccak256("2"), _chainId, address(this) )); } /** * @dev Set gameIdCntr. Can be only set before activating contract. */ function setGameIdCntr(uint _gameIdCntr) public onlyOwner onlyNotActivated { require(gameIdCntr > 0); gameIdCntr = _gameIdCntr; } /** * @notice Withdraw pending returns. */ function withdraw() public { uint toTransfer = pendingReturns[msg.sender]; require(toTransfer > 0); pendingReturns[msg.sender] = 0; msg.sender.transfer(toTransfer); } /** * @notice Transfer house profit to houseAddress. */ function transferProfitToHouse() public { require(lastProfitTransferTimestamp.add(profitTransferTimeSpan) <= block.timestamp); // update last transfer timestamp lastProfitTransferTimestamp = block.timestamp; if (houseProfit <= 0) { // no profit to transfer return; } uint toTransfer = houseProfit.castToUint(); houseProfit = 0; houseStake = houseStake.sub(toTransfer); houseAddress.transfer(toTransfer); } /** * @dev Set profit transfer time span. */ function setProfitTransferTimeSpan(uint _profitTransferTimeSpan) public onlyOwner onlyValidTransferTimeSpan(_profitTransferTimeSpan) { profitTransferTimeSpan = _profitTransferTimeSpan; } /** * @dev Increase house stake by msg.value */ function addHouseStake() public payable onlyOwner { houseStake = houseStake.add(msg.value); } /** * @dev Withdraw house stake. */ function withdrawHouseStake(uint value) public onlyOwner { uint minHouseStake = conflictRes.minHouseStake(activeGames); require(value <= houseStake && houseStake.sub(value) >= minHouseStake); require(houseProfit <= 0 || houseProfit.castToUint() <= houseStake.sub(value)); houseStake = houseStake.sub(value); owner.transfer(value); } /** * @dev Withdraw house stake and profit. */ function withdrawAll() public onlyOwner onlyPausedSince(3 days) { houseProfit = 0; uint toTransfer = houseStake; houseStake = 0; owner.transfer(toTransfer); } /** * @dev Set new house address. * @param _houseAddress New house address. */ function setHouseAddress(address payable _houseAddress) public onlyOwner { houseAddress = _houseAddress; } /** * @dev Set stake min and max value. * @param _minStake Min stake. * @param _maxStake Max stake. */ function setStakeRequirements(uint128 _minStake, uint128 _maxStake) public onlyOwner { require(_minStake > 0 && _minStake <= _maxStake); minStake = _minStake; maxStake = _maxStake; emit LogStakeLimitsModified(minStake, maxStake); } /** * @dev Close game session. * @param _game Game session data. * @param _gameId Id of game session. * @param _userAddress User's address of game session. * @param _reason Reason for closing game session. * @param _balance Game session balance. */ function closeGame( Game storage _game, uint _gameId, uint32 _roundId, address payable _userAddress, ReasonEnded _reason, int _balance ) internal { _game.status = GameStatus.ENDED; activeGames = activeGames.sub(1); payOut(_userAddress, _game.stake, _balance); emit LogGameEnded(_userAddress, _gameId, _roundId, _balance, _reason); } /** * @dev End game by paying out user and server. * @param _userAddress User's address. * @param _stake User's stake. * @param _balance User's balance. */ function payOut(address payable _userAddress, uint128 _stake, int _balance) internal { int stakeInt = _stake; int houseStakeInt = houseStake.castToInt(); assert(_balance <= conflictRes.maxBalance()); assert((stakeInt.add(_balance)) >= 0); if (_balance > 0 && houseStakeInt < _balance) { // Should never happen! // House is bankrupt. // Payout left money. _balance = houseStakeInt; } houseProfit = houseProfit.sub(_balance); int newHouseStake = houseStakeInt.sub(_balance); houseStake = newHouseStake.castToUint(); uint valueUser = stakeInt.add(_balance).castToUint(); pendingReturns[_userAddress] += valueUser; if (pendingReturns[_userAddress] > 0) { safeSend(_userAddress); } } /** * @dev Send value of pendingReturns[_address] to _address. * @param _address Address to send value to. */ function safeSend(address payable _address) internal { uint valueToSend = pendingReturns[_address]; assert(valueToSend > 0); pendingReturns[_address] = 0; if (_address.send(valueToSend) == false) { pendingReturns[_address] = valueToSend; } } /** * @dev Verify signature of given data. Throws on verification failure. * @param _sig Signature of given data in the form of rsv. * @param _address Address of signature signer. */ function verifySig( uint32 _roundId, uint8 _gameType, uint _num, uint _value, int _balance, bytes32 _serverHash, bytes32 _userHash, uint _gameId, address _contractAddress, bytes memory _sig, address _address ) internal view { // check if this is the correct contract address contractAddress = address(this); require(_contractAddress == contractAddress, "inv contractAddress"); bytes32 roundHash = calcHash( _roundId, _gameType, _num, _value, _balance, _serverHash, _userHash, _gameId ); verify( roundHash, _sig, _address ); } /** * @dev Check if _sig is valid signature of _hash. Throws if invalid signature. * @param _hash Hash to check signature of. * @param _sig Signature of _hash. * @param _address Address of signer. */ function verify( bytes32 _hash, bytes memory _sig, address _address ) internal pure { (bytes32 r, bytes32 s, uint8 v) = signatureSplit(_sig); address addressRecover = ecrecover(_hash, v, r, s); require(addressRecover == _address, "inv sig"); } /** * @dev Calculate typed hash of given data (compare eth_signTypedData). * @return Hash of given data. */ function calcHash( uint32 _roundId, uint8 _gameType, uint _num, uint _value, int _balance, bytes32 _serverHash, bytes32 _userHash, uint _gameId ) private view returns(bytes32) { bytes32 betHash = keccak256(abi.encode( BET_TYPEHASH, _roundId, _gameType, _num, _value, _balance, _serverHash, _userHash, _gameId )); return keccak256(abi.encodePacked( "\x19\x01", DOMAIN_SEPERATOR, betHash )); } /** * @dev Split the given signature of the form rsv in r s v. v is incremented with 27 if * it is below 2. * @param _signature Signature to split. * @return r s v */ function signatureSplit(bytes memory _signature) private pure returns (bytes32 r, bytes32 s, uint8 v) { require(_signature.length == 65, "inv sig"); assembly { r := mload(add(_signature, 32)) s := mload(add(_signature, 64)) v := and(mload(add(_signature, 65)), 0xff) } if (v < 2) { v = v + 27; } } } contract GameChannelConflict is GameChannelBase { using SafeCast for int; using SafeCast for uint; using SafeMath for int; using SafeMath for uint; /** * @dev Contract constructor. * @param _serverAddress Server address. * @param _minStake Min value user needs to deposit to create game session. * @param _maxStake Max value user can deposit to create game session. * @param _conflictResAddress Conflict resolution contract address * @param _houseAddress House address to move profit to * @param _chainId Chain id for signature domain. */ constructor( address _serverAddress, uint128 _minStake, uint128 _maxStake, address _conflictResAddress, address payable _houseAddress, uint _chainId ) public GameChannelBase(_serverAddress, _minStake, _maxStake, _conflictResAddress, _houseAddress, _chainId) { // nothing to do } /** * @dev Used by server if user does not end game session. * @param _roundId Round id of bet. * @param _gameType Game type of bet. * @param _num Number of bet. * @param _value Value of bet. * @param _balance Balance before this bet. * @param _serverHash Hash of server seed for this bet. * @param _userHash Hash of user seed for this bet. * @param _gameId Game session id. * @param _contractAddress Address of this contract. * @param _userSig User signature of this bet. * @param _userAddress Address of user. * @param _serverSeed Server seed for this bet. * @param _userSeed User seed for this bet. */ function serverEndGameConflict( uint32 _roundId, uint8 _gameType, uint _num, uint _value, int _balance, bytes32 _serverHash, bytes32 _userHash, uint _gameId, address _contractAddress, bytes memory _userSig, address payable _userAddress, bytes32 _serverSeed, bytes32 _userSeed ) public onlyServer { verifySig( _roundId, _gameType, _num, _value, _balance, _serverHash, _userHash, _gameId, _contractAddress, _userSig, _userAddress ); serverEndGameConflictImpl( _roundId, _gameType, _num, _value, _balance, _serverHash, _userHash, _serverSeed, _userSeed, _gameId, _userAddress ); } /** * @notice Can be used by user if server does not answer to the end game session request. * @param _roundId Round id of bet. * @param _gameType Game type of bet. * @param _num Number of bet. * @param _value Value of bet. * @param _balance Balance before this bet. * @param _serverHash Hash of server seed for this bet. * @param _userHash Hash of user seed for this bet. * @param _gameId Game session id. * @param _contractAddress Address of this contract. * @param _serverSig Server signature of this bet. * @param _userSeed User seed for this bet. */ function userEndGameConflict( uint32 _roundId, uint8 _gameType, uint _num, uint _value, int _balance, bytes32 _serverHash, bytes32 _userHash, uint _gameId, address _contractAddress, bytes memory _serverSig, bytes32 _userSeed ) public { verifySig( _roundId, _gameType, _num, _value, _balance, _serverHash, _userHash, _gameId, _contractAddress, _serverSig, serverAddress ); userEndGameConflictImpl( _roundId, _gameType, _num, _value, _balance, _userHash, _userSeed, _gameId, msg.sender ); } /** * @notice Cancel active game without playing. Useful if server stops responding before * one game is played. * @param _gameId Game session id. */ function userCancelActiveGame(uint _gameId) public { address payable userAddress = msg.sender; uint gameId = userGameId[userAddress]; Game storage game = gameIdGame[gameId]; require(gameId == _gameId, "inv gameId"); if (game.status == GameStatus.ACTIVE) { game.endInitiatedTime = block.timestamp; game.status = GameStatus.USER_INITIATED_END; emit LogUserRequestedEnd(msg.sender, gameId); } else if (game.status == GameStatus.SERVER_INITIATED_END && game.roundId == 0) { cancelActiveGame(game, gameId, userAddress); } else { revert(); } } /** * @dev Cancel active game without playing. Useful if user starts game session and * does not play. * @param _userAddress Users' address. * @param _gameId Game session id. */ function serverCancelActiveGame(address payable _userAddress, uint _gameId) public onlyServer { uint gameId = userGameId[_userAddress]; Game storage game = gameIdGame[gameId]; require(gameId == _gameId, "inv gameId"); if (game.status == GameStatus.ACTIVE) { game.endInitiatedTime = block.timestamp; game.status = GameStatus.SERVER_INITIATED_END; emit LogServerRequestedEnd(msg.sender, gameId); } else if (game.status == GameStatus.USER_INITIATED_END && game.roundId == 0) { cancelActiveGame(game, gameId, _userAddress); } else { revert(); } } /** * @dev Force end of game if user does not respond. Only possible after a certain period of time * to give the user a chance to respond. * @param _userAddress User's address. */ function serverForceGameEnd(address payable _userAddress, uint _gameId) public onlyServer { uint gameId = userGameId[_userAddress]; Game storage game = gameIdGame[gameId]; require(gameId == _gameId, "inv gameId"); require(game.status == GameStatus.SERVER_INITIATED_END, "inv status"); // theoretically we have enough data to calculate winner // but as user did not respond assume he has lost. int newBalance = conflictRes.serverForceGameEnd( game.gameType, game.betNum, game.betValue, game.balance, game.stake, game.serverSeed, game.userSeed, game.endInitiatedTime ); closeGame(game, gameId, game.roundId, _userAddress, ReasonEnded.SERVER_FORCED_END, newBalance); } /** * @notice Force end of game if server does not respond. Only possible after a certain period of time * to give the server a chance to respond. */ function userForceGameEnd(uint _gameId) public { address payable userAddress = msg.sender; uint gameId = userGameId[userAddress]; Game storage game = gameIdGame[gameId]; require(gameId == _gameId, "inv gameId"); require(game.status == GameStatus.USER_INITIATED_END, "inv status"); int newBalance = conflictRes.userForceGameEnd( game.gameType, game.betNum, game.betValue, game.balance, game.stake, game.endInitiatedTime ); closeGame(game, gameId, game.roundId, userAddress, ReasonEnded.USER_FORCED_END, newBalance); } /** * @dev Conflict handling implementation. Stores game data and timestamp if game * is active. If server has already marked conflict for game session the conflict * resolution contract is used (compare conflictRes). * @param _roundId Round id of bet. * @param _gameType Game type of bet. * @param _num Number of bet. * @param _value Value of bet. * @param _balance Balance before this bet. * @param _userHash Hash of user's seed for this bet. * @param _userSeed User's seed for this bet. * @param _gameId game Game session id. * @param _userAddress User's address. */ function userEndGameConflictImpl( uint32 _roundId, uint8 _gameType, uint _num, uint _value, int _balance, bytes32 _userHash, bytes32 _userSeed, uint _gameId, address payable _userAddress ) private { uint gameId = userGameId[_userAddress]; Game storage game = gameIdGame[gameId]; int maxBalance = conflictRes.maxBalance(); int gameStake = game.stake; require(gameId == _gameId, "inv gameId"); require(_roundId > 0, "inv roundId"); require(keccak256(abi.encodePacked(_userSeed)) == _userHash, "inv userSeed"); require(-gameStake <= _balance && _balance <= maxBalance, "inv balance"); // game.stake save to cast as uint128 require(conflictRes.isValidBet(_gameType, _num, _value), "inv bet"); require(gameStake.add(_balance).sub(_value.castToInt()) >= 0, "value too high"); // game.stake save to cast as uint128 if (game.status == GameStatus.SERVER_INITIATED_END && game.roundId == _roundId) { game.userSeed = _userSeed; endGameConflict(game, gameId, _userAddress); } else if (game.status == GameStatus.ACTIVE || (game.status == GameStatus.SERVER_INITIATED_END && game.roundId < _roundId)) { game.status = GameStatus.USER_INITIATED_END; game.endInitiatedTime = block.timestamp; game.roundId = _roundId; game.gameType = _gameType; game.betNum = _num; game.betValue = _value; game.balance = _balance; game.userSeed = _userSeed; game.serverSeed = bytes32(0); emit LogUserRequestedEnd(msg.sender, gameId); } else { revert("inv state"); } } /** * @dev Conflict handling implementation. Stores game data and timestamp if game * is active. If user has already marked conflict for game session the conflict * resolution contract is used (compare conflictRes). * @param _roundId Round id of bet. * @param _gameType Game type of bet. * @param _num Number of bet. * @param _value Value of bet. * @param _balance Balance before this bet. * @param _serverHash Hash of server's seed for this bet. * @param _userHash Hash of user's seed for this bet. * @param _serverSeed Server's seed for this bet. * @param _userSeed User's seed for this bet. * @param _userAddress User's address. */ function serverEndGameConflictImpl( uint32 _roundId, uint8 _gameType, uint _num, uint _value, int _balance, bytes32 _serverHash, bytes32 _userHash, bytes32 _serverSeed, bytes32 _userSeed, uint _gameId, address payable _userAddress ) private { uint gameId = userGameId[_userAddress]; Game storage game = gameIdGame[gameId]; int maxBalance = conflictRes.maxBalance(); int gameStake = game.stake; require(gameId == _gameId, "inv gameId"); require(_roundId > 0, "inv roundId"); require(keccak256(abi.encodePacked(_serverSeed)) == _serverHash, "inv serverSeed"); require(keccak256(abi.encodePacked(_userSeed)) == _userHash, "inv userSeed"); require(-gameStake <= _balance && _balance <= maxBalance, "inv balance"); // game.stake save to cast as uint128 require(conflictRes.isValidBet(_gameType, _num, _value), "inv bet"); require(gameStake.add(_balance).sub(_value.castToInt()) >= 0, "too high value"); // game.stake save to cast as uin128 if (game.status == GameStatus.USER_INITIATED_END && game.roundId == _roundId) { game.serverSeed = _serverSeed; endGameConflict(game, gameId, _userAddress); } else if (game.status == GameStatus.ACTIVE || (game.status == GameStatus.USER_INITIATED_END && game.roundId < _roundId)) { game.status = GameStatus.SERVER_INITIATED_END; game.endInitiatedTime = block.timestamp; game.roundId = _roundId; game.gameType = _gameType; game.betNum = _num; game.betValue = _value; game.balance = _balance; game.serverSeed = _serverSeed; game.userSeed = _userSeed; emit LogServerRequestedEnd(_userAddress, gameId); } else { revert("inv state"); } } /** * @dev End conflicting game without placed bets. * @param _game Game session data. * @param _gameId Game session id. * @param _userAddress User's address. */ function cancelActiveGame(Game storage _game, uint _gameId, address payable _userAddress) private { // user need to pay a fee when conflict ended. // this ensures a malicious, rich user can not just generate game sessions and then wait // for us to end the game session and then confirm the session status, so // we would have to pay a high gas fee without profit. int newBalance = -conflictRes.conflictEndFine(); // do not allow balance below user stake int stake = _game.stake; if (newBalance < -stake) { newBalance = -stake; } closeGame(_game, _gameId, 0, _userAddress, ReasonEnded.CONFLICT_ENDED, newBalance); } /** * @dev End conflicting game. * @param _game Game session data. * @param _gameId Game session id. * @param _userAddress User's address. */ function endGameConflict(Game storage _game, uint _gameId, address payable _userAddress) private { int newBalance = conflictRes.endGameConflict( _game.gameType, _game.betNum, _game.betValue, _game.balance, _game.stake, _game.serverSeed, _game.userSeed ); closeGame(_game, _gameId, _game.roundId, _userAddress, ReasonEnded.CONFLICT_ENDED, newBalance); } } contract GameChannel is GameChannelConflict { /** * @dev contract constructor * @param _serverAddress Server address. * @param _minStake Min value user needs to deposit to create game session. * @param _maxStake Max value user can deposit to create game session. * @param _conflictResAddress Conflict resolution contract address. * @param _houseAddress House address to move profit to. * @param _chainId Chain id for signature domain. */ constructor( address _serverAddress, uint128 _minStake, uint128 _maxStake, address _conflictResAddress, address payable _houseAddress, uint _chainId ) public GameChannelConflict(_serverAddress, _minStake, _maxStake, _conflictResAddress, _houseAddress, _chainId) { // nothing to do } /** * @notice Create games session request. msg.value needs to be valid stake value. * @param _userEndHash Last entry of users' hash chain. * @param _previousGameId User's previous game id, initial 0. * @param _createBefore Game can be only created before this timestamp. * @param _serverEndHash Last entry of server's hash chain. * @param _serverSig Server signature. See verifyCreateSig */ function createGame( bytes32 _userEndHash, uint _previousGameId, uint _createBefore, bytes32 _serverEndHash, bytes memory _serverSig ) public payable onlyValidValue onlyValidHouseStake(activeGames + 1) onlyNotPaused { uint previousGameId = userGameId[msg.sender]; Game storage game = gameIdGame[previousGameId]; require(game.status == GameStatus.ENDED, "prev game not ended"); require(previousGameId == _previousGameId, "inv gamePrevGameId"); require(block.timestamp < _createBefore, "expired"); verifyCreateSig(msg.sender, _previousGameId, _createBefore, _serverEndHash, _serverSig); uint gameId = gameIdCntr++; userGameId[msg.sender] = gameId; Game storage newGame = gameIdGame[gameId]; newGame.stake = uint128(msg.value); // It's safe to cast msg.value as it is limited, see onlyValidValue newGame.status = GameStatus.ACTIVE; activeGames = activeGames.add(1); // It's safe to cast msg.value as it is limited, see onlyValidValue emit LogGameCreated(msg.sender, gameId, uint128(msg.value), _serverEndHash, _userEndHash); } /** * @dev Regular end game session. Used if user and house have both * accepted current game session state. * The game session with gameId _gameId is closed * and the user paid out. This functions is called by the server after * the user requested the termination of the current game session. * @param _roundId Round id of bet. * @param _balance Current balance. * @param _serverHash Hash of server's seed for this bet. * @param _userHash Hash of user's seed for this bet. * @param _gameId Game session id. * @param _contractAddress Address of this contract. * @param _userAddress Address of user. * @param _userSig User's signature of this bet. */ function serverEndGame( uint32 _roundId, int _balance, bytes32 _serverHash, bytes32 _userHash, uint _gameId, address _contractAddress, address payable _userAddress, bytes memory _userSig ) public onlyServer { verifySig( _roundId, 0, 0, 0, _balance, _serverHash, _userHash, _gameId, _contractAddress, _userSig, _userAddress ); regularEndGame(_userAddress, _roundId, _balance, _gameId, _contractAddress); } /** * @notice Regular end game session. Normally not needed as server ends game (@see serverEndGame). * Can be used by user if server does not end game session. * @param _roundId Round id of bet. * @param _balance Current balance. * @param _serverHash Hash of server's seed for this bet. * @param _userHash Hash of user's seed for this bet. * @param _gameId Game session id. * @param _contractAddress Address of this contract. * @param _serverSig Server's signature of this bet. */ function userEndGame( uint32 _roundId, int _balance, bytes32 _serverHash, bytes32 _userHash, uint _gameId, address _contractAddress, bytes memory _serverSig ) public { verifySig( _roundId, 0, 0, 0, _balance, _serverHash, _userHash, _gameId, _contractAddress, _serverSig, serverAddress ); regularEndGame(msg.sender, _roundId, _balance, _gameId, _contractAddress); } /** * @dev Verify server signature. * @param _userAddress User's address. * @param _previousGameId User's previous game id, initial 0. * @param _createBefore Game can be only created before this timestamp. * @param _serverEndHash Last entry of server's hash chain. * @param _serverSig Server signature. */ function verifyCreateSig( address _userAddress, uint _previousGameId, uint _createBefore, bytes32 _serverEndHash, bytes memory _serverSig ) private view { address contractAddress = address(this); bytes32 hash = keccak256(abi.encodePacked( contractAddress, _userAddress, _previousGameId, _createBefore, _serverEndHash )); verify(hash, _serverSig, serverAddress); } /** * @dev Regular end game session implementation. Used if user and house have both * accepted current game session state. The game session with gameId _gameId is closed * and the user paid out. * @param _userAddress Address of user. * @param _balance Current balance. * @param _gameId Game session id. * @param _contractAddress Address of this contract. */ function regularEndGame( address payable _userAddress, uint32 _roundId, int _balance, uint _gameId, address _contractAddress ) private { uint gameId = userGameId[_userAddress]; Game storage game = gameIdGame[gameId]; int maxBalance = conflictRes.maxBalance(); int gameStake = game.stake; require(_gameId == gameId, "inv gameId"); require(_roundId > 0, "inv roundId"); // save to cast as game.stake hash fixed range require(-gameStake <= _balance && _balance <= maxBalance, "inv balance"); require(game.status == GameStatus.ACTIVE, "inv status"); assert(_contractAddress == address(this)); closeGame(game, gameId, _roundId, _userAddress, ReasonEnded.REGULAR_ENDED, _balance); } } library SafeCast { /** * Cast unsigned a to signed a. */ function castToInt(uint a) internal pure returns(int) { assert(a < (1 << 255)); return int(a); } /** * Cast signed a to unsigned a. */ function castToUint(int a) internal pure returns(uint) { assert(a >= 0); return uint(a); } } library SafeMath { /** * @dev Multiplies two unsigned integers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting '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; } c = a * b; assert(c / a == b); return c; } /** * @dev Multiplies two signed integers, throws on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than asserting '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; } int256 c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two unsigned integers, truncating the quotient. */ 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 a / b; } /** * @dev Integer division of two signed integers, truncating the quotient. */ function div(int256 a, int256 b) internal pure returns (int256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 // Overflow only happens when the smallest negative int is multiplied by -1. int256 INT256_MIN = int256((uint256(1) << 255)); assert(a != INT256_MIN || b != - 1); return a / b; } /** * @dev Subtracts two unsigned integers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Subtracts two signed integers, throws on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; assert((b >= 0 && c <= a) || (b < 0 && c > a)); return c; } /** * @dev Adds two unsigned integers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } /** * @dev Adds two signed integers, throws on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; assert((b >= 0 && c >= a) || (b < 0 && c < a)); return c; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"DOMAIN_SEPERATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"activate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"activated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_TRANSFER_TIMESPAN","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"userGameId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"pendingReturns","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_gameIdCntr","type":"uint256"}],"name":"setGameIdCntr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"profitTransferTimeSpan","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minStake","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_roundId","type":"uint32"},{"name":"_balance","type":"int256"},{"name":"_serverHash","type":"bytes32"},{"name":"_userHash","type":"bytes32"},{"name":"_gameId","type":"uint256"},{"name":"_contractAddress","type":"address"},{"name":"_userAddress","type":"address"},{"name":"_userSig","type":"bytes"}],"name":"serverEndGame","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastProfitTransferTimestamp","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BET_TYPEHASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"addHouseStake","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"MIN_TIMEOUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"timePaused","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"conflictRes","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"withdrawHouseStake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"destroy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"gameIdGame","outputs":[{"name":"status","type":"uint8"},{"name":"stake","type":"uint128"},{"name":"gameType","type":"uint8"},{"name":"roundId","type":"uint32"},{"name":"betNum","type":"uint256"},{"name":"betValue","type":"uint256"},{"name":"balance","type":"int256"},{"name":"userSeed","type":"bytes32"},{"name":"serverSeed","type":"bytes32"},{"name":"endInitiatedTime","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_roundId","type":"uint32"},{"name":"_gameType","type":"uint8"},{"name":"_num","type":"uint256"},{"name":"_value","type":"uint256"},{"name":"_balance","type":"int256"},{"name":"_serverHash","type":"bytes32"},{"name":"_userHash","type":"bytes32"},{"name":"_gameId","type":"uint256"},{"name":"_contractAddress","type":"address"},{"name":"_serverSig","type":"bytes"},{"name":"_userSeed","type":"bytes32"}],"name":"userEndGameConflict","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"houseProfit","outputs":[{"name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_roundId","type":"uint32"},{"name":"_gameType","type":"uint8"},{"name":"_num","type":"uint256"},{"name":"_value","type":"uint256"},{"name":"_balance","type":"int256"},{"name":"_serverHash","type":"bytes32"},{"name":"_userHash","type":"bytes32"},{"name":"_gameId","type":"uint256"},{"name":"_contractAddress","type":"address"},{"name":"_userSig","type":"bytes"},{"name":"_userAddress","type":"address"},{"name":"_serverSeed","type":"bytes32"},{"name":"_userSeed","type":"bytes32"}],"name":"serverEndGameConflict","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_TRANSFER_TIMSPAN","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_gameId","type":"uint256"}],"name":"userCancelActiveGame","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_profitTransferTimeSpan","type":"uint256"}],"name":"setProfitTransferTimeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"activateConflictResolution","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newConflictRes","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_userAddress","type":"address"},{"name":"_gameId","type":"uint256"}],"name":"serverCancelActiveGame","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_userEndHash","type":"bytes32"},{"name":"_previousGameId","type":"uint256"},{"name":"_createBefore","type":"uint256"},{"name":"_serverEndHash","type":"bytes32"},{"name":"_serverSig","type":"bytes"}],"name":"createGame","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_gameId","type":"uint256"}],"name":"userForceGameEnd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"TIMEOUT_DESTROY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712DOMAIN_TYPEHASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"houseStake","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newConflictResAddress","type":"address"}],"name":"updateConflictResolution","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_userAddress","type":"address"},{"name":"_gameId","type":"uint256"}],"name":"serverForceGameEnd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_minStake","type":"uint128"},{"name":"_maxStake","type":"uint128"}],"name":"setStakeRequirements","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"houseAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"serverAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"updateTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_TIMEOUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"activeGames","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_roundId","type":"uint32"},{"name":"_balance","type":"int256"},{"name":"_serverHash","type":"bytes32"},{"name":"_userHash","type":"bytes32"},{"name":"_gameId","type":"uint256"},{"name":"_contractAddress","type":"address"},{"name":"_serverSig","type":"bytes"}],"name":"userEndGame","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxStake","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_houseAddress","type":"address"}],"name":"setHouseAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gameIdCntr","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"transferProfitToHouse","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_serverAddress","type":"address"},{"name":"_minStake","type":"uint128"},{"name":"_maxStake","type":"uint128"},{"name":"_conflictResAddress","type":"address"},{"name":"_houseAddress","type":"address"},{"name":"_chainId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"gameId","type":"uint256"},{"indexed":false,"name":"stake","type":"uint128"},{"indexed":true,"name":"serverEndHash","type":"bytes32"},{"indexed":false,"name":"userEndHash","type":"bytes32"}],"name":"LogGameCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"gameId","type":"uint256"}],"name":"LogUserRequestedEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"gameId","type":"uint256"}],"name":"LogServerRequestedEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"gameId","type":"uint256"},{"indexed":false,"name":"roundId","type":"uint32"},{"indexed":false,"name":"balance","type":"int256"},{"indexed":false,"name":"reason","type":"uint8"}],"name":"LogGameEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minStake","type":"uint256"},{"indexed":false,"name":"maxStake","type":"uint256"}],"name":"LogStakeLimitsModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newConflictResolutionAddress","type":"address"}],"name":"LogUpdatingConflictResolution","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newConflictResolutionAddress","type":"address"}],"name":"LogUpdatedConflictResolution","type":"event"},{"anonymous":false,"inputs":[],"name":"LogPause","type":"event"},{"anonymous":false,"inputs":[],"name":"LogUnpause","type":"event"},{"anonymous":false,"inputs":[],"name":"LogActive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"LogOwnerShipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"LogOwnerShipTransferInitiated","type":"event"}]
Contract Creation Code
60806040526001805460a060020a61ffff02191675010000000000000000000000000000000000000000001781554260025560048054600160a060020a0319169055600060058190556007819055600891909155600b819055600c5562127500600e553480156200006f57600080fd5b5060405160c08062003da1833981018060405260c08110156200009157600080fd5b508051602082015160408301516060840151608085015160a0909501516000805433600160a060020a0319918216178255600180548216905560038054909116600160a060020a03851617905594959394929391928690869086908690869086908690869086908690869086906001608060020a038616118015620001285750836001608060020a0316856001608060020a031611155b15156200013457600080fd5b60098054600160a060020a03978816600160a060020a031991821617909155600a8054939097169216919091179094555042600f55600d80546001608060020a03928316700100000000000000000000000000000000029383166001608060020a031990911617909116919091179055604080517f454950373132446f6d61696e28737472696e67206e616d652c737472696e672081527f76657273696f6e2c75696e7432353620636861696e49642c61646472657373206020808301919091527f766572696679696e67436f6e74726163742900000000000000000000000000008284015282519182900360520182207f4469636574686572000000000000000000000000000000000000000000000000835283519283900360080183207f3200000000000000000000000000000000000000000000000000000000000000845284519384900360010184208484019290925283850152606083015260808201939093523060a0808301919091528251808303909101815260c09091019091528051910120600655505050505050505050505050613ac880620002d96000396000f3fe6080604052600436106102795763ffffffff60e060020a6000350416630df63210811461027e5780630f15f4c0146102a5578063186601ca146102bc57806319fc36ed146102e55780631b08345a146102fa57806326b387bb1461032d578063287e9fbc146103605780632c94a2351461038a578063375b3c0a1461039f5780633ccfd60b146103d05780633f4ba83a146103e5578063410453ae146103fa57806341b80184146104ed5780634d20d4bc146105025780634e71e0c8146105175780634f739ff01461052c578063543ad1df14610534578063563c23a0146105495780635ba2dd221461055e5780635c975abb1461058f57806381efc01d146105a457806383197ef0146105ce57806383e256dc146105e35780638456cb5914610686578063853828b61461069b578063878de0ae146106b057806388fedd04146107b25780638da5cb5b146107c75780639399dd7e146107dc578063947bc72d146108f05780639b29f133146109055780639c0051db1461092f5780639f34ce1414610959578063a09f86591461096e578063a8182cd314610983578063afc81953146109bc578063b064ca1814610a7a578063bd5c4e2414610aa4578063c49f91d314610ab9578063c861f3a014610ace578063cbffb1ae14610ae3578063d1e9dcbf14610b16578063d6e5fe9814610b4f578063d7cee31e14610b8a578063db420fe314610b9f578063dc55509014610bb4578063de38eb3a14610bc9578063e30c397814610bde578063e475222e14610bf3578063e60a33aa14610c08578063ea1b28e014610cee578063ef3aaf5414610d03578063f2fde38b14610d36578063f87ffb7414610d69578063fd306ca714610d7e575b600080fd5b34801561028a57600080fd5b50610293610d93565b60408051918252519081900360200190f35b3480156102b157600080fd5b506102ba610d99565b005b3480156102c857600080fd5b506102d1610e16565b604080519115158252519081900360200190f35b3480156102f157600080fd5b50610293610e26565b34801561030657600080fd5b506102936004803603602081101561031d57600080fd5b5035600160a060020a0316610e2d565b34801561033957600080fd5b506102936004803603602081101561035057600080fd5b5035600160a060020a0316610e3f565b34801561036c57600080fd5b506102ba6004803603602081101561038357600080fd5b5035610e51565b34801561039657600080fd5b50610293610e93565b3480156103ab57600080fd5b506103b4610e99565b604080516001608060020a039092168252519081900360200190f35b3480156103dc57600080fd5b506102ba610ea8565b3480156103f157600080fd5b506102ba610f03565b34801561040657600080fd5b506102ba600480360361010081101561041e57600080fd5b63ffffffff82351691602081013591604082013591606081013591608082013591600160a060020a0360a082013581169260c08301359091169190810190610100810160e082013564010000000081111561047857600080fd5b82018360208201111561048a57600080fd5b803590602001918460018302840111640100000000831117156104ac57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f99945050505050565b3480156104f957600080fd5b50610293610fdc565b34801561050e57600080fd5b50610293610fe2565b34801561052357600080fd5b506102ba610ffd565b6102ba61107b565b34801561054057600080fd5b506102936110aa565b34801561055557600080fd5b506102936110b1565b34801561056a57600080fd5b506105736110b7565b60408051600160a060020a039092168252519081900360200190f35b34801561059b57600080fd5b506102d16110c6565b3480156105b057600080fd5b506102ba600480360360208110156105c757600080fd5b50356110d6565b3480156105da57600080fd5b506102ba611241565b3480156105ef57600080fd5b5061060d6004803603602081101561060657600080fd5b50356112a2565b604051808b600381111561061d57fe5b60ff90811682526001608060020a03909b166020820152989099166040808a019190915263ffffffff9097166060890152608088019590955260a087019390935260c086019190915260e085015261010084015261012083015251908190036101400192509050f35b34801561069257600080fd5b506102ba611317565b3480156106a757600080fd5b506102ba6113e4565b3480156106bc57600080fd5b506102ba60048036036101608110156106d457600080fd5b63ffffffff8235169160ff6020820135169160408201359160608101359160808201359160a08101359160c08201359160e081013591600160a060020a03610100830135169190810190610140810161012082013564010000000081111561073b57600080fd5b82018360208201111561074d57600080fd5b8035906020019184600183028401116401000000008311171561076f57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505091359250611480915050565b3480156107be57600080fd5b506102936114c6565b3480156107d357600080fd5b506105736114cc565b3480156107e857600080fd5b506102ba60048036036101a081101561080057600080fd5b63ffffffff8235169160ff6020820135169160408201359160608101359160808201359160a08101359160c08201359160e081013591600160a060020a03610100830135169190810190610140810161012082013564010000000081111561086757600080fd5b82018360208201111561087957600080fd5b8035906020019184600183028401116401000000008311171561089b57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050600160a060020a0383351693505050602081013590604001356114db565b3480156108fc57600080fd5b50610293611527565b34801561091157600080fd5b506102ba6004803603602081101561092857600080fd5b503561152e565b34801561093b57600080fd5b506102ba6004803603602081101561095257600080fd5b503561162d565b34801561096557600080fd5b506102ba61166c565b34801561097a57600080fd5b5061057361173e565b34801561098f57600080fd5b506102ba600480360360408110156109a657600080fd5b50600160a060020a03813516906020013561174d565b6102ba600480360360a08110156109d257600080fd5b81359160208101359160408201359160608101359181019060a081016080820135640100000000811115610a0557600080fd5b820183602082011115610a1757600080fd5b80359060200191846001830284011164010000000083111715610a3957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611866945050505050565b348015610a8657600080fd5b506102ba60048036036020811015610a9d57600080fd5b5035611c54565b348015610ab057600080fd5b50610293611e3b565b348015610ac557600080fd5b50610293611e42565b348015610ada57600080fd5b50610293611ec2565b348015610aef57600080fd5b506102ba60048036036020811015610b0657600080fd5b5035600160a060020a0316611ec8565b348015610b2257600080fd5b506102ba60048036036040811015610b3957600080fd5b50600160a060020a038135169060200135611f44565b348015610b5b57600080fd5b506102ba60048036036040811015610b7257600080fd5b506001608060020a038135811691602001351661215c565b348015610b9657600080fd5b50610573612236565b348015610bab57600080fd5b50610573612245565b348015610bc057600080fd5b50610293612254565b348015610bd557600080fd5b5061029361225a565b348015610bea57600080fd5b50610573612261565b348015610bff57600080fd5b50610293612270565b348015610c1457600080fd5b506102ba600480360360e0811015610c2b57600080fd5b63ffffffff82351691602081013591604082013591606081013591608082013591600160a060020a0360a0820135169181019060e0810160c0820135640100000000811115610c7957600080fd5b820183602082011115610c8b57600080fd5b80359060200191846001830284011164010000000083111715610cad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612276945050505050565b348015610cfa57600080fd5b506103b46122b6565b348015610d0f57600080fd5b506102ba60048036036020811015610d2657600080fd5b5035600160a060020a03166122d9565b348015610d4257600080fd5b506102ba60048036036020811015610d5957600080fd5b5035600160a060020a031661231f565b348015610d7557600080fd5b50610293612394565b348015610d8a57600080fd5b506102ba61239a565b60065481565b600054600160a060020a03163314610db057600080fd5b60015460a060020a900460ff1615610dc757600080fd5b6001805474ff0000000000000000000000000000000000000000191660a060020a1790556040517fc9d6bebde85c4e3348468c6af2cb34f978d1a8c6eebc438f1361c1ad5edf5f0e90600090a1565b60015460a060020a900460ff1681565b6201518081565b60116020526000908152604090205481565b60126020526000908152604090205481565b600054600160a060020a03163314610e6857600080fd5b60015460a060020a900460ff1615610e7f57600080fd5b600854600010610e8e57600080fd5b600855565b600e5481565b600d546001608060020a031681565b33600090815260126020526040812054908111610ec457600080fd5b336000818152601260205260408082208290555183156108fc0291849190818181858888f19350505050158015610eff573d6000803e3d6000fd5b5050565b600054600160a060020a03163314610f1a57600080fd5b60015460a860020a900460ff161515610f3257600080fd5b60015460a060020a900460ff161515610f4a57600080fd5b6001805475ff00000000000000000000000000000000000000000019169055600060028190556040517f730c1faaa977b67dacf1e2451ef54556e04a07d577785ff79f6d31f73502efc99190a1565b600954600160a060020a03163314610fb057600080fd5b610fc58860008060008b8b8b8b8b8a8c612437565b610fd282898987876124b7565b5050505050505050565b600f5481565b604051806081613a1c82396081019050604051809103902081565b600154600160a060020a0316331461101457600080fd5b6001805460008054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff1992831617808455919093169093556040519092909116907f897d3c8bbea11029ba3b26eb993fe8edb14c2c4c0d2ecceccce41d1d83d3e359908390a3565b600054600160a060020a0316331461109257600080fd5b600b546110a5903463ffffffff61270f16565b600b55565b6203f48081565b60025481565b600354600160a060020a031681565b60015460a860020a900460ff1681565b600054600160a060020a031633146110ed57600080fd5b600354600754604080517f73c4726b000000000000000000000000000000000000000000000000000000008152600481019290925251600092600160a060020a0316916373c4726b916024808301926020929190829003018186803b15801561115557600080fd5b505afa158015611169573d6000803e3d6000fd5b505050506040513d602081101561117f57600080fd5b5051600b5490915082118015906111a95750600b5481906111a6908463ffffffff61272216565b10155b15156111b457600080fd5b6000600c541315806111e25750600b546111d4908363ffffffff61272216565b6111df600c54612734565b11155b15156111ed57600080fd5b600b54611200908363ffffffff61272216565b600b5560008054604051600160a060020a039091169184156108fc02918591818181858888f1935050505015801561123c573d6000803e3d6000fd5b505050565b600054600160a060020a0316331461125857600080fd5b600154621a5e009060a860020a900460ff16801561128957506002544290611286908363ffffffff61270f16565b11155b151561129457600080fd5b600054600160a060020a0316ff5b601060205260009081526040902080546001820154600283015460038401546004850154600586015460069096015460ff8087169761010088046001608060020a03169771010000000000000000000000000000000000810490921696609060020a90920463ffffffff16959194919391928a565b600054600160a060020a0316331461132e57600080fd5b60015460a860020a900460ff1615611390576040805160e560020a62461bcd02815260206004820152600660248201527f7061757365640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001805475ff000000000000000000000000000000000000000000191660a860020a179055426002556040517f4b314b34e912fda7f95e7d23e9c8c95f82f0aff1984e4ce592a0b005f905562490600090a1565b600054600160a060020a031633146113fb57600080fd5b6001546203f4809060a860020a900460ff16801561142c57506002544290611429908363ffffffff61270f16565b11155b151561143757600080fd5b6000600c819055600b80549082905581546040519192600160a060020a039091169183156108fc0291849190818181858888f1935050505015801561123c573d6000803e3d6000fd5b6114a88b8b8b8b8b8b8b8b8b8b600960009054906101000a9004600160a060020a0316612437565b6114b98b8b8b8b8b8a878b33612744565b5050505050505050505050565b600c5481565b600054600160a060020a031681565b600954600160a060020a031633146114f257600080fd5b6115058d8d8d8d8d8d8d8d8d8d8d612437565b6115188d8d8d8d8d8d8d89898f8d612ca7565b50505050505050505050505050565b62ed4e0081565b336000818152601160209081526040808320548084526010909252909120838214611591576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b6001815460ff1660038111156115a357fe5b14156115ec57426006820155805460ff19166002178155604051829033907f9b60ba122ac2e613ae737820a8eb2d8c28356ff6b03d569dacb7ce2bcdc86fed90600090a3611627565b6003815460ff1660038111156115fe57fe5b14801561161757508054609060020a900463ffffffff16155b156102795761162781838561324a565b50505050565b600054600160a060020a0316331461164457600080fd5b8062015180811015801561165b575062ed4e008111155b151561166657600080fd5b50600e55565b600054600160a060020a0316331461168357600080fd5b600454600160a060020a0316151561169a57600080fd5b60055415156116a857600080fd5b426203f48060055401111580156116c657506207e900600554014211155b15156116d157600080fd5b600480546003805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551690556000600581905560408051918252517f28de3c2df3d09a8b061f86cd0c78b7d02f1f5caffcd086ff45ee12a4a51056c89181900360200190a1565b600454600160a060020a031681565b600954600160a060020a0316331461176457600080fd5b600160a060020a03821660009081526011602090815260408083205480845260109092529091208282146117d0576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b6001815460ff1660038111156117e257fe5b141561182b57426006820155805460ff19166003178155604051829033907fdbbc392d5391708a9def7f560f8cbdef92e1bb37e5104831e78feda1488b7ab090600090a3611627565b6002815460ff16600381111561183d57fe5b14801561185657508054609060020a900463ffffffff16155b156102795761162781838661324a565b600d54346001608060020a03909116118015906118a25750600d5470010000000000000000000000000000000090046001608060020a03163411155b15156118f8576040805160e560020a62461bcd02815260206004820152600960248201527f696e76207374616b650000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600754600354604080517f73c4726b00000000000000000000000000000000000000000000000000000000815260019093016004840181905290519092600092600160a060020a0316916373c4726b91602480820192602092909190829003018186803b15801561196857600080fd5b505afa15801561197c573d6000803e3d6000fd5b505050506040513d602081101561199257600080fd5b5051600b549091508111156119f1576040805160e560020a62461bcd02815260206004820152600e60248201527f696e7620686f7573655374616b65000000000000000000000000000000000000604482015290519081900360640190fd5b60015460a860020a900460ff1615611a53576040805160e560020a62461bcd02815260206004820152600660248201527f7061757365640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b33600090815260116020908152604080832054808452601090925282209091815460ff166003811115611a8257fe5b14611ad7576040805160e560020a62461bcd02815260206004820152601360248201527f707265762067616d65206e6f7420656e64656400000000000000000000000000604482015290519081900360640190fd5b818814611b2e576040805160e560020a62461bcd02815260206004820152601260248201527f696e762067616d655072657647616d6549640000000000000000000000000000604482015290519081900360640190fd5b428711611b85576040805160e560020a62461bcd02815260206004820152600760248201527f6578706972656400000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611b92338989898961330d565b60088054600180820190925533600090815260116020908152604080832084905583835260109091529020805470ffffffffffffffffffffffffffffffff001916610100346001608060020a0316021760ff19168317815560075491929091611bfa9161270f565b600755604080516001608060020a0334168152602081018d905281518a92859233927fd25faca801440882fa5d7c7f70b072a2ad89621e277ee0b6f9923ccac48411b1929181900390910190a45050505050505050505050565b336000818152601160209081526040808320548084526010909252909120838214611cb7576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b6002815460ff166003811115611cc957fe5b14611d1e576040805160e560020a62461bcd02815260206004820152600a60248201527f696e762073746174757300000000000000000000000000000000000000000000604482015290519081900360640190fd5b60038054825460018401546002850154938501546006860154604080517f0c5ebb1a00000000000000000000000000000000000000000000000000000000815271010000000000000000000000000000000000860460ff1660048201526024810194909452604484019690965260648301919091526101009092046001608060020a0316608482015260a48101919091529151600092600160a060020a0390921691630c5ebb1a9160c4808301926020929190829003018186803b158015611de557600080fd5b505afa158015611df9573d6000803e3d6000fd5b505050506040513d6020811015611e0f57600080fd5b50518254909150611e349083908590609060020a900463ffffffff1687600286613384565b5050505050565b621a5e0081565b604080517f454950373132446f6d61696e28737472696e67206e616d652c737472696e672081527f76657273696f6e2c75696e7432353620636861696e49642c616464726573732060208201527f766572696679696e67436f6e747261637429000000000000000000000000000081830152905190819003605201902081565b600b5481565b600054600160a060020a03163314611edf57600080fd5b60048054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff1990911681179091554260055560408051918252517f97044e884f04922f1959ef2de012f4734423df2d4da57fd4c5eaf40cd63b525f9181900360200190a150565b600954600160a060020a03163314611f5b57600080fd5b600160a060020a0382166000908152601160209081526040808320548084526010909252909120828214611fc7576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b6003815460ff166003811115611fd957fe5b1461202e576040805160e560020a62461bcd02815260206004820152600a60248201527f696e762073746174757300000000000000000000000000000000000000000000604482015290519081900360640190fd5b600380548254600184015460028501549385015460058601546004808801546006890154604080517f8a94839a00000000000000000000000000000000000000000000000000000000815271010000000000000000000000000000000000890460ff16948101949094526024840196909652604483019890985260648201939093526101009094046001608060020a0316608485015260a484015260c483015260e48201939093529151600092600160a060020a0390921691638a94839a91610104808301926020929190829003018186803b15801561210d57600080fd5b505afa158015612121573d6000803e3d6000fd5b505050506040513d602081101561213757600080fd5b50518254909150611e349083908590609060020a900463ffffffff1688600186613384565b600054600160a060020a0316331461217357600080fd5b6000826001608060020a031611801561219e5750806001608060020a0316826001608060020a031611155b15156121a957600080fd5b600d80546fffffffffffffffffffffffffffffffff19166001608060020a038481169190911781167001000000000000000000000000000000008483168102919091179283905560408051848416815291909304909116602082015281517f1ec948cac143dba0e555a87dd86ae387e2ecd4a8fee80f7dd324d5987cb3e7f8929181900390910190a15050565b600a54600160a060020a031681565b600954600160a060020a031681565b60055481565b6207e90081565b600154600160a060020a031681565b60075481565b6122a08760008060008a8a8a8a8a8a600960009054906101000a9004600160a060020a0316612437565b6122ad33888886866124b7565b50505050505050565b600d5470010000000000000000000000000000000090046001608060020a031681565b600054600160a060020a031633146122f057600080fd5b600a805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600054600160a060020a0316331461233657600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383811691821790925560008054604051929316917f83ada3430836f9d4bd6f7bc690ffbba5199cb19b37393dd64c229930213535969190a350565b60085481565b426123b2600e54600f5461270f90919063ffffffff16565b11156123bd57600080fd5b42600f55600c546000126123d057612435565b60006123dd600c54612734565b6000600c55600b549091506123f8908263ffffffff61272216565b600b55600a54604051600160a060020a039091169082156108fc029083906000818181858888f19350505050158015610eff573d6000803e3d6000fd5b565b30600160a060020a0384168114612498576040805160e560020a62461bcd02815260206004820152601360248201527f696e7620636f6e74726163744164647265737300000000000000000000000000604482015290519081900360640190fd5b60006124aa8d8d8d8d8d8d8d8d61342d565b9050611518818585613506565b600160a060020a038086166000908152601160209081526040808320548084526010835281842060035483517f73ad468a000000000000000000000000000000000000000000000000000000008152935192969195949116926373ad468a9260048083019392829003018186803b15801561253157600080fd5b505afa158015612545573d6000803e3d6000fd5b505050506040513d602081101561255b57600080fd5b5051825490915061010090046001608060020a03168386146125b5576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b600063ffffffff891611612613576040805160e560020a62461bcd02815260206004820152600b60248201527f696e7620726f756e644964000000000000000000000000000000000000000000604482015290519081900360640190fd5b8681600003131580156126265750818713155b151561267c576040805160e560020a62461bcd02815260206004820152600b60248201527f696e762062616c616e6365000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001835460ff16600381111561268e57fe5b146126e3576040805160e560020a62461bcd02815260206004820152600a60248201527f696e762073746174757300000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03851630146126f557fe5b61270483858a8c60008c613384565b505050505050505050565b8181018281101561271c57fe5b92915050565b60008282111561272e57fe5b50900390565b60008082121561274057fe5b5090565b600160a060020a038082166000908152601160209081526040808320548084526010835281842060035483517f73ad468a000000000000000000000000000000000000000000000000000000008152935192969195949116926373ad468a9260048083019392829003018186803b1580156127be57600080fd5b505afa1580156127d2573d6000803e3d6000fd5b505050506040513d60208110156127e857600080fd5b5051825490915061010090046001608060020a0316858414612842576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b600063ffffffff8e16116128a0576040805160e560020a62461bcd02815260206004820152600b60248201527f696e7620726f756e644964000000000000000000000000000000000000000000604482015290519081900360640190fd5b6040805160208082018a905282518083038201815291830190925280519101208814612916576040805160e560020a62461bcd02815260206004820152600c60248201527f696e762075736572536565640000000000000000000000000000000000000000604482015290519081900360640190fd5b8881600003131580156129295750818913155b151561297f576040805160e560020a62461bcd02815260206004820152600b60248201527f696e762062616c616e6365000000000000000000000000000000000000000000604482015290519081900360640190fd5b600354604080517f09eecdd700000000000000000000000000000000000000000000000000000000815260ff8f166004820152602481018e9052604481018d90529051600160a060020a03909216916309eecdd791606480820192602092909190829003018186803b1580156129f457600080fd5b505afa158015612a08573d6000803e3d6000fd5b505050506040513d6020811015612a1e57600080fd5b50511515612a76576040805160e560020a62461bcd02815260206004820152600760248201527f696e762062657400000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000612aa0612a848c6135e9565b612a94848d63ffffffff61361416565b9063ffffffff61364d16565b1215612af6576040805160e560020a62461bcd02815260206004820152600e60248201527f76616c756520746f6f2068696768000000000000000000000000000000000000604482015290519081900360640190fd5b6003835460ff166003811115612b0857fe5b148015612b255750825463ffffffff8e8116609060020a90920416145b15612b415760048301879055612b3c83858761367c565b611518565b6001835460ff166003811115612b5357fe5b1480612b8957506003835460ff166003811115612b6c57fe5b148015612b895750825463ffffffff808f16609060020a90920416105b15612c57578254600290849060ff191660018302179055504283600601819055508c8360000160126101000a81548163ffffffff021916908363ffffffff1602179055508b8360000160116101000a81548160ff021916908360ff1602179055508a8360010181905550898360020181905550888360030181905550868360040181905550600060010283600501819055508333600160a060020a03167f9b60ba122ac2e613ae737820a8eb2d8c28356ff6b03d569dacb7ce2bcdc86fed60405160405180910390a3611518565b6040805160e560020a62461bcd02815260206004820152600960248201527f696e762073746174650000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038082166000908152601160209081526040808320548084526010835281842060035483517f73ad468a000000000000000000000000000000000000000000000000000000008152935192969195949116926373ad468a9260048083019392829003018186803b158015612d2157600080fd5b505afa158015612d35573d6000803e3d6000fd5b505050506040513d6020811015612d4b57600080fd5b5051825490915061010090046001608060020a0316858414612da5576040805160e560020a62461bcd02815260206004820152600a60248201526000805160206139fc833981519152604482015290519081900360640190fd5b60008f63ffffffff16111515612e05576040805160e560020a62461bcd02815260206004820152600b60248201527f696e7620726f756e644964000000000000000000000000000000000000000000604482015290519081900360640190fd5b6040805160208082018b905282518083038201815291830190925280519101208a14612e7b576040805160e560020a62461bcd02815260206004820152600e60248201527f696e762073657276657253656564000000000000000000000000000000000000604482015290519081900360640190fd5b6040805160208082018a905282518083038201815291830190925280519101208914612ef1576040805160e560020a62461bcd02815260206004820152600c60248201527f696e762075736572536565640000000000000000000000000000000000000000604482015290519081900360640190fd5b8a8160000313158015612f045750818b13155b1515612f5a576040805160e560020a62461bcd02815260206004820152600b60248201527f696e762062616c616e6365000000000000000000000000000000000000000000604482015290519081900360640190fd5b600360009054906101000a9004600160a060020a0316600160a060020a03166309eecdd78f8f8f6040518463ffffffff1660e060020a028152600401808460ff1660ff168152602001838152602001828152602001935050505060206040518083038186803b158015612fcc57600080fd5b505afa158015612fe0573d6000803e3d6000fd5b505050506040513d6020811015612ff657600080fd5b5051151561304e576040805160e560020a62461bcd02815260206004820152600760248201527f696e762062657400000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600061306c61305c8e6135e9565b612a94848f63ffffffff61361416565b12156130c2576040805160e560020a62461bcd02815260206004820152600e60248201527f746f6f20686967682076616c7565000000000000000000000000000000000000604482015290519081900360640190fd5b6002835460ff1660038111156130d457fe5b14801561310057508e63ffffffff168360000160129054906101000a900463ffffffff1663ffffffff16145b1561311c576005830188905561311783858761367c565b613239565b6001835460ff16600381111561312e57fe5b148061317357506002835460ff16600381111561314757fe5b14801561317357508e63ffffffff168360000160129054906101000a900463ffffffff1663ffffffff16105b15612c57578254600390849060ff191660018302179055504283600601819055508e8360000160126101000a81548163ffffffff021916908363ffffffff1602179055508d8360000160116101000a81548160ff021916908360ff1602179055508c83600101819055508b83600201819055508a83600301819055508783600501819055508683600401819055508385600160a060020a03167fdbbc392d5391708a9def7f560f8cbdef92e1bb37e5104831e78feda1488b7ab060405160405180910390a35b505050505050505050505050505050565b600354604080517ffcec617a0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163fcec617a916004808301926020929190829003018186803b1580156132a857600080fd5b505afa1580156132bc573d6000803e3d6000fd5b505050506040513d60208110156132d257600080fd5b505184546000918203925061010090046001608060020a0316908190038212156132fd578060000391505b611e348585600086600387613384565b604080516c0100000000000000000000000030818102602080850191909152600160a060020a03808b169093026034850152604884018990526068840188905260888085018890528551808603909101815260a89094019094528251929093019190912060095490916122ad918391869116613506565b855460ff1916865560075461339a906001612722565b60075585546133b990849061010090046001608060020a0316836137a2565b8483600160a060020a03167f59ba0efd7d5a5d7e109fb346b50365a8d68661fc7c2c311cd29750707e1b8de5868486604051808463ffffffff1663ffffffff16815260200183815260200182600381111561341057fe5b60ff168152602001935050505060405180910390a3505050505050565b6000806040518080613a1c608191396040805191829003608101822060208084019190915263ffffffff9d909d168282015260ff9b909b166060820152608081019990995250505060a086019490945260c085019290925260e08401526101008301526101208083019190915282518083039091018152610140820183528051908401206006547f190100000000000000000000000000000000000000000000000000000000000061016084015261016283015261018280830191909152825180830390910181526101a2909101909152805191012090565b6000806000613514856138f9565b925092509250600060018783868660405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613579573d6000803e3d6000fd5b5050604051601f190151915050600160a060020a03808216908616146122ad576040805160e560020a62461bcd02815260206004820152600760248201527f696e762073696700000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60007f8000000000000000000000000000000000000000000000000000000000000000821061274057fe5b60008282018183128015906136295750838112155b8061363e575060008312801561363e57508381125b151561364657fe5b9392505050565b60008183038183128015906136625750838113155b8061363e575060008312801561363e575083811361364657fe5b600380548454600186015460028701549387015460058801546004808a0154604080517f2a0763ce00000000000000000000000000000000000000000000000000000000815271010000000000000000000000000000000000880460ff16938101939093526024830195909552604482019790975260648101929092526101009093046001608060020a0316608482015260a481019290925260c48201939093529151600092600160a060020a0390921691632a0763ce9160e4808301926020929190829003018186803b15801561375357600080fd5b505afa158015613767573d6000803e3d6000fd5b505050506040513d602081101561377d57600080fd5b505184549091506116279085908590609060020a900463ffffffff1685600386613384565b6000826001608060020a0316905060006137bd600b546135e9565b9050600360009054906101000a9004600160a060020a0316600160a060020a03166373ad468a6040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561381057600080fd5b505afa158015613824573d6000803e3d6000fd5b505050506040513d602081101561383a57600080fd5b505183131561384557fe5b6000613857838563ffffffff61361416565b121561385f57fe5b60008313801561386e57508281125b15613877578092505b600c5461388a908463ffffffff61364d16565b600c55600061389f828563ffffffff61364d16565b90506138aa81612734565b600b5560006138c76138c2858763ffffffff61361416565b612734565b600160a060020a0388166000908152601260205260408120805483019081905591925010156122ad576122ad87613982565b600080600083516041141515613959576040805160e560020a62461bcd02815260206004820152600760248201527f696e762073696700000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b50505060208101516040820151604183015160ff16600281101561397b57601b015b9193909250565b600160a060020a0381166000908152601260205260408120549081116139a457fe5b600160a060020a0382166000818152601260205260408082208290555183156108fc0291849190818181858888f115159350610eff9250505057600160a060020a039190911660009081526012602052604090205556fe696e762067616d654964000000000000000000000000000000000000000000004265742875696e74333220726f756e6449642c75696e74382067616d65547970652c75696e74323536206e756d6265722c75696e743235362076616c75652c696e743235362062616c616e63652c6279746573333220736572766572486173682c627974657333322075736572486173682c75696e743235362067616d65496429a165627a7a723058202962893aac580bbd54efca1473f7c82957764476c99a6a8af781c563e454f7f20029000000000000000000000000cef260a5fed7a896bbe07b933b3a5c17aec094d8000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000001a055690d9db8000000000000000000000000000045a0b6eef5857ecb504da583d549c620fe35301600000000000000000000000071be1ace87248f3950bdfc4c89b4b3eed059f6f30000000000000000000000000000000000000000000000000000000000000001
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cef260a5fed7a896bbe07b933b3a5c17aec094d8000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000001a055690d9db8000000000000000000000000000045a0b6eef5857ecb504da583d549c620fe35301600000000000000000000000071be1ace87248f3950bdfc4c89b4b3eed059f6f30000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _serverAddress (address): 0xCef260a5Fed7A896BBE07b933B3A5c17aEC094D8
Arg [1] : _minStake (uint128): 10000000000000000
Arg [2] : _maxStake (uint128): 30000000000000000000
Arg [3] : _conflictResAddress (address): 0x45a0b6EEF5857ECb504dA583d549C620fE353016
Arg [4] : _houseAddress (address): 0x71BE1aCe87248F3950BdFc4c89b4B3EED059f6f3
Arg [5] : _chainId (uint256): 1
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000cef260a5fed7a896bbe07b933b3a5c17aec094d8
Arg [1] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [2] : 000000000000000000000000000000000000000000000001a055690d9db80000
Arg [3] : 00000000000000000000000045a0b6eef5857ecb504da583d549c620fe353016
Arg [4] : 00000000000000000000000071be1ace87248f3950bdfc4c89b4b3eed059f6f3
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Swarm Source
bzzr://2962893aac580bbd54efca1473f7c82957764476c99a6a8af781c563e454f7f2
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.