ETH Price: $3,363.49 (-2.59%)

Contract

0x6A20D74106F28Ad19C60115917FF363Ad71F525F
 

Overview

ETH Balance

1.05021 ETH

Eth Value

$3,532.37 (@ $3,363.49/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw Battle ...201829162024-06-27 12:06:23182 days ago1719489983IN
0x6A20D741...Ad71F525F
0 ETH0.000310095.30679625
Transfer Block V...201829162024-06-27 12:06:23182 days ago1719489983IN
0x6A20D741...Ad71F525F
0 ETH0.000413155.30679625
Attack Tile For ...201829162024-06-27 12:06:23182 days ago1719489983IN
0x6A20D741...Ad71F525F
0.001 ETH0.001106595.30679625
Withdraw Battle ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000254894.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000832784.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000833834.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000833834.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000835374.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000833834.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.00033984.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000832784.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000836144.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000835374.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.000339754.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.000836144.36397165
Transfer Block V...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0 ETH0.00033984.36397165
Attack Tile For ...201828922024-06-27 12:01:35182 days ago1719489695IN
0x6A20D741...Ad71F525F
0.001 ETH0.00090744.36397165
Withdraw Battle ...201828872024-06-27 12:00:35182 days ago1719489635IN
0x6A20D741...Ad71F525F
0 ETH0.000237384.06243406
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
201829162024-06-27 12:06:23182 days ago1719489983
0x6A20D741...Ad71F525F
0.0027075 ETH
201828922024-06-27 12:01:35182 days ago1719489695
0x6A20D741...Ad71F525F
0.0361 ETH
201828872024-06-27 12:00:35182 days ago1719489635
0x6A20D741...Ad71F525F
0.0550525 ETH
201828782024-06-27 11:58:47182 days ago1719489527
0x6A20D741...Ad71F525F
0.05415 ETH
201828672024-06-27 11:56:35182 days ago1719489395
0x6A20D741...Ad71F525F
0.05415 ETH
201828602024-06-27 11:55:11182 days ago1719489311
0x6A20D741...Ad71F525F
0.05415 ETH
201828452024-06-27 11:52:11182 days ago1719489131
0x6A20D741...Ad71F525F
0.0442225 ETH
201828412024-06-27 11:51:23182 days ago1719489083
0x6A20D741...Ad71F525F
0.03249 ETH
201689872024-06-25 13:26:59184 days ago1719322019
0x6A20D741...Ad71F525F
0.05415 ETH
201566922024-06-23 20:11:35186 days ago1719173495
0x6A20D741...Ad71F525F
0.059565 ETH
201502992024-06-22 22:44:23187 days ago1719096263
0x6A20D741...Ad71F525F
0.027075 ETH
201397142024-06-21 11:11:23188 days ago1718968283
0x6A20D741...Ad71F525F
0.027075 ETH
201292822024-06-20 0:11:35190 days ago1718842295
0x6A20D741...Ad71F525F
0.01444 ETH
201228252024-06-19 2:30:59191 days ago1718764259
0x6A20D741...Ad71F525F
0.00722 ETH
103088302020-06-21 11:24:381649 days ago1592738678
0x6A20D741...Ad71F525F
0.4275 ETH
60668772018-08-01 3:38:382339 days ago1533094718
0x6A20D741...Ad71F525F
0.019855 ETH
60432662018-07-28 4:41:162343 days ago1532752876
0x6A20D741...Ad71F525F
0.212705 ETH
59844112018-07-18 4:26:402353 days ago1531888000
0x6A20D741...Ad71F525F
0.0791825 ETH
59778392018-07-17 1:20:412355 days ago1531790441
0x6A20D741...Ad71F525F
0.2674725 ETH
59704992018-07-15 19:25:342356 days ago1531682734
0x6A20D741...Ad71F525F
0.0063175 ETH
59300582018-07-08 23:56:262363 days ago1531094186
0x6A20D741...Ad71F525F
0.0300675 ETH
58753912018-06-29 14:54:222372 days ago1530284062
0x6A20D741...Ad71F525F
0.2755 ETH
58608692018-06-27 2:43:032375 days ago1530067383
0x6A20D741...Ad71F525F
0.0604675 ETH
58475672018-06-24 18:53:092377 days ago1529866389
0x6A20D741...Ad71F525F
0.045315 ETH
58238802018-06-20 18:05:162381 days ago1529517916
0x6A20D741...Ad71F525F
0.0099275 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BW

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-06-07
*/

pragma solidity ^0.4.21;

library BWUtility {
    
    // -------- UTILITY FUNCTIONS ----------


    // Return next higher even _multiple for _amount parameter (e.g used to round up to even finneys).
    function ceil(uint _amount, uint _multiple) pure public returns (uint) {
        return ((_amount + _multiple - 1) / _multiple) * _multiple;
    }

    // Checks if two coordinates are adjacent:
    // xxx
    // xox
    // xxx
    // All x (_x2, _xy2) are adjacent to o (_x1, _y1) in this ascii image. 
    // Adjacency does not wrapp around map edges so if y2 = 255 and y1 = 0 then they are not ajacent
    function isAdjacent(uint8 _x1, uint8 _y1, uint8 _x2, uint8 _y2) pure public returns (bool) {
        return ((_x1 == _x2 &&      (_y2 - _y1 == 1 || _y1 - _y2 == 1))) ||      // Same column
               ((_y1 == _y2 &&      (_x2 - _x1 == 1 || _x1 - _x2 == 1))) ||      // Same row
               ((_x2 - _x1 == 1 &&  (_y2 - _y1 == 1 || _y1 - _y2 == 1))) ||      // Right upper or lower diagonal
               ((_x1 - _x2 == 1 &&  (_y2 - _y1 == 1 || _y1 - _y2 == 1)));        // Left upper or lower diagonal
    }

    // Converts (x, y) to tileId xy
    function toTileId(uint8 _x, uint8 _y) pure public returns (uint16) {
        return uint16(_x) << 8 | uint16(_y);
    }

    // Converts _tileId to (x, y)
    function fromTileId(uint16 _tileId) pure public returns (uint8, uint8) {
        uint8 y = uint8(_tileId);
        uint8 x = uint8(_tileId >> 8);
        return (x, y);
    }
    
    function getBoostFromTile(address _claimer, address _attacker, address _defender, uint _blockValue) pure public returns (uint, uint) {
        if (_claimer == _attacker) {
            return (_blockValue, 0);
        } else if (_claimer == _defender) {
            return (0, _blockValue);
        }
    }
}






interface ERC20I {
    function transfer(address _recipient, uint256 _amount) external returns (bool);
    function balanceOf(address _holder) external view returns (uint256);
}


contract BWService {
    using SafeMath for uint256;
    address private owner;
    address private bw;
    address private bwMarket;
    BWData private bwData;
    uint private seed = 42;
    uint private WITHDRAW_FEE = 5; // 5%
    uint private ATTACK_FEE = 5; // 5%
    uint private ATTACK_BOOST_CAP = 300; // 300%
    uint private DEFEND_BOOST_CAP = 300; // 300%
    uint private ATTACK_BOOST_MULTIPLIER = 100; // 100%
    uint private DEFEND_BOOST_MULTIPLIER = 100; // 100%
    mapping (uint16 => address) private localGames;
    
    modifier isOwner {
        if (msg.sender != owner) {
            revert();
        }
        _;
    }  

    modifier isValidCaller {
        if (msg.sender != bw && msg.sender != bwMarket) {
            revert();
        }
        _;
    }

    event TileClaimed(uint16 tileId, address newClaimer, uint priceInWei, uint creationTime);
    event TileFortified(uint16 tileId, address claimer, uint addedValueInWei, uint priceInWei, uint fortifyTime); // Sent when a user fortifies an existing claim by bumping its value.
    event TileAttackedSuccessfully(uint16 tileId, address attacker, uint attackAmount, uint totalAttackAmount, address defender, uint defendAmount, uint totalDefendAmount, uint attackRoll, uint attackTime); // Sent when a user successfully attacks a tile.    
    event TileDefendedSuccessfully(uint16 tileId, address attacker, uint attackAmount, uint totalAttackAmount, address defender, uint defendAmount, uint totalDefendAmount, uint attackRoll, uint defendTime); // Sent when a user successfully defends a tile when attacked.    
    event BlockValueMoved(uint16 sourceTileId, uint16 destTileId, address owner, uint movedBlockValue, uint postSourceValue, uint postDestValue, uint moveTime); // Sent when a user buys a tile from another user, by accepting a tile offer
    event UserBattleValueUpdated(address userAddress, uint battleValue, bool isWithdraw);

    // Constructor.
    constructor(address _bwData) public {
        bwData = BWData(_bwData);
        owner = msg.sender;
    }

    // Can't send funds straight to this contract. Avoid people sending by mistake.
    function () payable public {
        revert();
    }

    // OWNER-ONLY FUNCTIONS
    function kill() public isOwner {
        selfdestruct(owner);
    }

    function setValidBwCaller(address _bw) public isOwner {
        bw = _bw;
    }
    
    function setValidBwMarketCaller(address _bwMarket) public isOwner {
        bwMarket = _bwMarket;
    }

    function setWithdrawFee(uint _feePercentage) public isOwner {
        WITHDRAW_FEE = _feePercentage;
    }

    function setAttackFee(uint _feePercentage) public isOwner {
        ATTACK_FEE = _feePercentage;
    }

    function setAttackBoostMultipler(uint _multiplierPercentage) public isOwner {
        ATTACK_BOOST_MULTIPLIER = _multiplierPercentage;
    }

    function setDefendBoostMultiplier(uint _multiplierPercentage) public isOwner {
        DEFEND_BOOST_MULTIPLIER = _multiplierPercentage;
    }

    function setAttackBoostCap(uint _capPercentage) public isOwner {
        ATTACK_BOOST_CAP = _capPercentage;
    }

    function setDefendBoostCap(uint _capPercentage) public isOwner {
        DEFEND_BOOST_CAP = _capPercentage;
    }

    // TILE-RELATED FUNCTIONS
    // This function claims multiple previously unclaimed tiles in a single transaction.
    // The value assigned to each tile is the msg.value divided by the number of tiles claimed.
    // The msg.value is required to be an even multiple of the number of tiles claimed.
    function storeInitialClaim(address _msgSender, uint16[] _claimedTileIds, uint _claimAmount, bool _useBattleValue) public isValidCaller {
        uint tileCount = _claimedTileIds.length;
        require(tileCount > 0);
        require(_claimAmount >= 1 finney * tileCount); // ensure enough funds paid for all tiles
        require(_claimAmount % tileCount == 0); // ensure payment is an even multiple of number of tiles claimed

        uint valuePerBlockInWei = _claimAmount.div(tileCount); // Due to requires above this is guaranteed to be an even number
        require(valuePerBlockInWei >= 5 finney);

        if (_useBattleValue) {
            subUserBattleValue(_msgSender, _claimAmount, false);  
        }

        addGlobalBlockValueBalance(_claimAmount);

        uint16 tileId;
        bool isNewTile;
        for (uint16 i = 0; i < tileCount; i++) {
            tileId = _claimedTileIds[i];
            isNewTile = bwData.isNewTile(tileId); // Is length 0 if first time purchased
            require(isNewTile); // Can only claim previously unclaimed tiles.

            // Send claim event
            emit TileClaimed(tileId, _msgSender, valuePerBlockInWei, block.timestamp);

            // Update contract state with new tile ownership.
            bwData.storeClaim(tileId, _msgSender, valuePerBlockInWei);
        }
    }

    function fortifyClaims(address _msgSender, uint16[] _claimedTileIds, uint _fortifyAmount, bool _useBattleValue) public isValidCaller {
        uint tileCount = _claimedTileIds.length;
        require(tileCount > 0);

        address(this).balance.add(_fortifyAmount); // prevent overflow with SafeMath
        require(_fortifyAmount % tileCount == 0); // ensure payment is an even multiple of number of tiles fortified
        uint addedValuePerTileInWei = _fortifyAmount.div(tileCount); // Due to requires above this is guaranteed to be an even number
        require(_fortifyAmount >= 1 finney * tileCount); // ensure enough funds paid for all tiles

        address claimer;
        uint blockValue;
        for (uint16 i = 0; i < tileCount; i++) {
            (claimer, blockValue) = bwData.getTileClaimerAndBlockValue(_claimedTileIds[i]);
            require(claimer != 0); // Can't do this on never-owned tiles
            require(claimer == _msgSender); // Only current claimer can fortify claim

            if (_useBattleValue) {
                subUserBattleValue(_msgSender, addedValuePerTileInWei, false);
            }
            
            fortifyClaim(_msgSender, _claimedTileIds[i], addedValuePerTileInWei);
        }
    }

    function fortifyClaim(address _msgSender, uint16 _claimedTileId, uint _fortifyAmount) private {
        uint blockValue;
        uint sellPrice;
        (blockValue, sellPrice) = bwData.getCurrentBlockValueAndSellPriceForTile(_claimedTileId);
        uint updatedBlockValue = blockValue.add(_fortifyAmount);
        // Send fortify event
        emit TileFortified(_claimedTileId, _msgSender, _fortifyAmount, updatedBlockValue, block.timestamp);
        
        // Update tile value. The tile has been fortified by bumping up its value.
        bwData.updateTileBlockValue(_claimedTileId, updatedBlockValue);

        // Track addition to global block value
        addGlobalBlockValueBalance(_fortifyAmount);
    }

    // Return a pseudo random number between lower and upper bounds
    // given the number of previous blocks it should hash.
    // Random function copied from https://github.com/axiomzen/eth-random/blob/master/contracts/Random.sol.
    // Changed sha3 to keccak256, then modified.
    // Changed random range from uint64 to uint (=uint256).
    function random(uint _upper) private returns (uint)  {
        seed = uint(keccak256(blockhash(block.number - 1), block.coinbase, block.timestamp, seed, address(0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE).balance));
        return seed % _upper;
    }

    // A user tries to claim a tile that's already owned by another user. A battle ensues.
    // A random roll is done with % based on attacking vs defending amounts.
    function attackTile(address _msgSender, uint16 _tileId, uint _attackAmount, bool _useBattleValue) public isValidCaller {
        require(_attackAmount >= 1 finney);         // Don't allow attacking with less than one base tile price.
        require(_attackAmount % 1 finney == 0);

        address claimer;
        uint blockValue;
        (claimer, blockValue) = bwData.getTileClaimerAndBlockValue(_tileId);
        
        require(claimer != 0); // Can't do this on never-owned tiles
        require(claimer != _msgSender); // Can't attack one's own tiles
        require(claimer != owner); // Can't attack owner's tiles because it is used for raffle.

        // Calculate boosted amounts for attacker and defender
        // The base attack amount is sent in the by the user.
        // The base defend amount is the attacked tile's current blockValue.
        uint attackBoost;
        uint defendBoost;
        (attackBoost, defendBoost) = bwData.calculateBattleBoost(_tileId, _msgSender, claimer);

        // Adjust boost to optimize game strategy
        attackBoost = attackBoost.mul(ATTACK_BOOST_MULTIPLIER).div(100);
        defendBoost = defendBoost.mul(DEFEND_BOOST_MULTIPLIER).div(100);
        
        // Cap the boost to minimize its impact (prevents whales somehow)
        if (attackBoost > _attackAmount.mul(ATTACK_BOOST_CAP).div(100)) {
            attackBoost = _attackAmount.mul(ATTACK_BOOST_CAP).div(100);
        }
        if (defendBoost > blockValue.mul(DEFEND_BOOST_CAP).div(100)) {
            defendBoost = blockValue.mul(DEFEND_BOOST_CAP).div(100);
        }

        uint totalAttackAmount = _attackAmount.add(attackBoost);
        uint totalDefendAmount = blockValue.add(defendBoost);

        // Verify that attack odds are within allowed range.
        require(totalAttackAmount.div(10) <= totalDefendAmount); // Disallow attacks with more than 1000% of defendAmount
        require(totalAttackAmount >= totalDefendAmount.div(10)); // Disallow attacks with less than 10% of defendAmount

        uint attackFeeAmount = _attackAmount.mul(ATTACK_FEE).div(100);
        uint attackAmountAfterFee = _attackAmount.sub(attackFeeAmount);
        
        updateFeeBalance(attackFeeAmount);

        // The battle considers boosts.
        uint attackRoll = random(totalAttackAmount.add(totalDefendAmount)); // This is where the excitement happens!

        //gas cost of attack branch is higher than denfense branch solving MSB1
        if (attackRoll > totalDefendAmount) {
            // Change block owner but keep same block value (attacker got battlevalue instead)
            bwData.setClaimerForTile(_tileId, _msgSender);

            // Tile successfully attacked!
            if (_useBattleValue) {
                // Withdraw followed by deposit of same amount to prevent MSB1
                addUserBattleValue(_msgSender, attackAmountAfterFee); // Don't include boost here!
                subUserBattleValue(_msgSender, attackAmountAfterFee, false);
            } else {
                addUserBattleValue(_msgSender, attackAmountAfterFee); // Don't include boost here!
            }
            addUserBattleValue(claimer, 0);

            bwData.updateTileTimeStamp(_tileId);
            // Send update event
            emit TileAttackedSuccessfully(_tileId, _msgSender, attackAmountAfterFee, totalAttackAmount, claimer, blockValue, totalDefendAmount, attackRoll, block.timestamp);
        } else {
            bwData.setClaimerForTile(_tileId, claimer); //should be old owner
            // Tile successfully defended!
            if (_useBattleValue) {
                subUserBattleValue(_msgSender, attackAmountAfterFee, false); // Don't include boost here!
            }
            addUserBattleValue(claimer, attackAmountAfterFee); // Don't include boost here!
            
            // Send update event
            emit TileDefendedSuccessfully(_tileId, _msgSender, attackAmountAfterFee, totalAttackAmount, claimer, blockValue, totalDefendAmount, attackRoll, block.timestamp);
        }
    }

    function updateFeeBalance(uint attackFeeAmount) private {
        uint feeBalance = bwData.getFeeBalance();
        feeBalance = feeBalance.add(attackFeeAmount);
        bwData.setFeeBalance(feeBalance);
    }

    function moveBlockValue(address _msgSender, uint8 _xSource, uint8 _ySource, uint8 _xDest, uint8 _yDest, uint _moveAmount) public isValidCaller {
        uint16 sourceTileId = BWUtility.toTileId(_xSource, _ySource);
        uint16 destTileId = BWUtility.toTileId(_xDest, _yDest);

        address sourceTileClaimer;
        address destTileClaimer;
        uint sourceTileBlockValue;
        uint destTileBlockValue;
        (sourceTileClaimer, sourceTileBlockValue) = bwData.getTileClaimerAndBlockValue(sourceTileId);
        (destTileClaimer, destTileBlockValue) = bwData.getTileClaimerAndBlockValue(destTileId);

        uint newBlockValue = sourceTileBlockValue.sub(_moveAmount);
        // Must transfer the entire block value or leave at least 5
        require(newBlockValue == 0 || newBlockValue >= 5 finney);

        require(sourceTileClaimer == _msgSender);
        require(destTileClaimer == _msgSender);
        require(_moveAmount >= 1 finney); // Can't be less
        require(_moveAmount % 1 finney == 0); // Move amount must be in multiples of 1 finney
        // require(sourceTile.blockValue - _moveAmount >= BASE_TILE_PRICE_WEI); // Must always leave some at source
        
        require(BWUtility.isAdjacent(_xSource, _ySource, _xDest, _yDest));

        sourceTileBlockValue = sourceTileBlockValue.sub(_moveAmount);
        destTileBlockValue = destTileBlockValue.add(_moveAmount);

        // If ALL block value was moved away from the source tile, we lose our claim to it. It becomes ownerless.
        if (sourceTileBlockValue == 0) {
            bwData.deleteTile(sourceTileId);
        } else {
            bwData.updateTileBlockValue(sourceTileId, sourceTileBlockValue);
            bwData.deleteOffer(sourceTileId); // Offer invalid since block value has changed
        }

        bwData.updateTileBlockValue(destTileId, destTileBlockValue);
        bwData.deleteOffer(destTileId);   // Offer invalid since block value has changed
        emit BlockValueMoved(sourceTileId, destTileId, _msgSender, _moveAmount, sourceTileBlockValue, destTileBlockValue, block.timestamp);        
    }

    function verifyAmount(address _msgSender, uint _msgValue, uint _amount, bool _useBattleValue) view public isValidCaller {
        if (_useBattleValue) {
            require(_msgValue == 0);
            require(bwData.getUserBattleValue(_msgSender) >= _amount);
        } else {
            require(_amount == _msgValue);
        }
    }

    function setLocalGame(uint16 _tileId, address localGameAddress) public isOwner {
        localGames[_tileId] = localGameAddress;
    }

    function getLocalGame(uint16 _tileId) view public isValidCaller returns (address) {
        return localGames[_tileId];
    }

    // BATTLE VALUE FUNCTIONS
    function withdrawBattleValue(address msgSender, uint _battleValueInWei) public isValidCaller returns (uint) {
        //require(_battleValueInWei % 1 finney == 0); // Must be divisible by 1 finney
        uint fee = _battleValueInWei.mul(WITHDRAW_FEE).div(100); // Since we divide by 20 we can never create infinite fractions, so we'll always count in whole wei amounts.
        uint amountToWithdraw = _battleValueInWei.sub(fee);
        uint feeBalance = bwData.getFeeBalance();
        feeBalance = feeBalance.add(fee);
        bwData.setFeeBalance(feeBalance);
        subUserBattleValue(msgSender, _battleValueInWei, true);
        return amountToWithdraw;
    }

    function addUserBattleValue(address _userId, uint _amount) public isValidCaller {
        uint userBattleValue = bwData.getUserBattleValue(_userId);
        uint newBattleValue = userBattleValue.add(_amount);
        bwData.setUserBattleValue(_userId, newBattleValue); // Don't include boost here!
        emit UserBattleValueUpdated(_userId, newBattleValue, false);
    }
    
    function subUserBattleValue(address _userId, uint _amount, bool _isWithdraw) public isValidCaller {
        uint userBattleValue = bwData.getUserBattleValue(_userId);
        require(_amount <= userBattleValue); // Must be less than user's battle value - also implicitly checks that underflow isn't possible
        uint newBattleValue = userBattleValue.sub(_amount);
        bwData.setUserBattleValue(_userId, newBattleValue); // Don't include boost here!
        emit UserBattleValueUpdated(_userId, newBattleValue, _isWithdraw);
    }

    function addGlobalBlockValueBalance(uint _amount) public isValidCaller {
        // Track addition to global block value.
        uint blockValueBalance = bwData.getBlockValueBalance();
        bwData.setBlockValueBalance(blockValueBalance.add(_amount));
    }

    function subGlobalBlockValueBalance(uint _amount) public isValidCaller {
        // Track addition to global block value.
        uint blockValueBalance = bwData.getBlockValueBalance();
        bwData.setBlockValueBalance(blockValueBalance.sub(_amount));
    }

    // Allow us to transfer out airdropped tokens if we ever receive any
    function transferTokens(address _tokenAddress, address _recipient) public isOwner {
        ERC20I token = ERC20I(_tokenAddress);
        require(token.transfer(_recipient, token.balanceOf(this)));
    }
}





contract BWData {
    address public owner;
    address private bwService;
    address private bw;
    address private bwMarket;

    uint private blockValueBalance = 0;
    uint private feeBalance = 0;
    uint private BASE_TILE_PRICE_WEI = 1 finney; // 1 milli-ETH.
    
    mapping (address => User) private users; // user address -> user information
    mapping (uint16 => Tile) private tiles; // tileId -> list of TileClaims for that particular tile
    
    // Info about the users = those who have purchased tiles.
    struct User {
        uint creationTime;
        bool censored;
        uint battleValue;
    }

    // Info about a tile ownership
    struct Tile {
        address claimer;
        uint blockValue;
        uint creationTime;
        uint sellPrice;    // If 0 -> not on marketplace. If > 0 -> on marketplace.
    }

    struct Boost {
        uint8 numAttackBoosts;
        uint8 numDefendBoosts;
        uint attackBoost;
        uint defendBoost;
    }

    constructor() public {
        owner = msg.sender;
    }

    // Can't send funds straight to this contract. Avoid people sending by mistake.
    function () payable public {
        revert();
    }

    function kill() public isOwner {
        selfdestruct(owner);
    }

    modifier isValidCaller {
        if (msg.sender != bwService && msg.sender != bw && msg.sender != bwMarket) {
            revert();
        }
        _;
    }
    
    modifier isOwner {
        if (msg.sender != owner) {
            revert();
        }
        _;
    }
    
    function setBwServiceValidCaller(address _bwService) public isOwner {
        bwService = _bwService;
    }

    function setBwValidCaller(address _bw) public isOwner {
        bw = _bw;
    }

    function setBwMarketValidCaller(address _bwMarket) public isOwner {
        bwMarket = _bwMarket;
    }    
    
    // ----------USER-RELATED GETTER FUNCTIONS------------
    
    //function getUser(address _user) view public returns (bytes32) {
        //BWUtility.User memory user = users[_user];
        //require(user.creationTime != 0);
        //return (user.creationTime, user.imageUrl, user.tag, user.email, user.homeUrl, user.creationTime, user.censored, user.battleValue);
    //}
    
    function addUser(address _msgSender) public isValidCaller {
        User storage user = users[_msgSender];
        require(user.creationTime == 0);
        user.creationTime = block.timestamp;
    }

    function hasUser(address _user) view public isValidCaller returns (bool) {
        return users[_user].creationTime != 0;
    }
    

    // ----------TILE-RELATED GETTER FUNCTIONS------------

    function getTile(uint16 _tileId) view public isValidCaller returns (address, uint, uint, uint) {
        Tile storage currentTile = tiles[_tileId];
        return (currentTile.claimer, currentTile.blockValue, currentTile.creationTime, currentTile.sellPrice);
    }
    
    function getTileClaimerAndBlockValue(uint16 _tileId) view public isValidCaller returns (address, uint) {
        Tile storage currentTile = tiles[_tileId];
        return (currentTile.claimer, currentTile.blockValue);
    }
    
    function isNewTile(uint16 _tileId) view public isValidCaller returns (bool) {
        Tile storage currentTile = tiles[_tileId];
        return currentTile.creationTime == 0;
    }
    
    function storeClaim(uint16 _tileId, address _claimer, uint _blockValue) public isValidCaller {
        tiles[_tileId] = Tile(_claimer, _blockValue, block.timestamp, 0);
    }

    function updateTileBlockValue(uint16 _tileId, uint _blockValue) public isValidCaller {
        tiles[_tileId].blockValue = _blockValue;
    }

    function setClaimerForTile(uint16 _tileId, address _claimer) public isValidCaller {
        tiles[_tileId].claimer = _claimer;
    }

    function updateTileTimeStamp(uint16 _tileId) public isValidCaller {
        tiles[_tileId].creationTime = block.timestamp;
    }
    
    function getCurrentClaimerForTile(uint16 _tileId) view public isValidCaller returns (address) {
        Tile storage currentTile = tiles[_tileId];
        if (currentTile.creationTime == 0) {
            return 0;
        }
        return currentTile.claimer;
    }

    function getCurrentBlockValueAndSellPriceForTile(uint16 _tileId) view public isValidCaller returns (uint, uint) {
        Tile storage currentTile = tiles[_tileId];
        if (currentTile.creationTime == 0) {
            return (0, 0);
        }
        return (currentTile.blockValue, currentTile.sellPrice);
    }
    
    function getBlockValueBalance() view public isValidCaller returns (uint){
        return blockValueBalance;
    }

    function setBlockValueBalance(uint _blockValueBalance) public isValidCaller {
        blockValueBalance = _blockValueBalance;
    }

    function getFeeBalance() view public isValidCaller returns (uint) {
        return feeBalance;
    }

    function setFeeBalance(uint _feeBalance) public isValidCaller {
        feeBalance = _feeBalance;
    }
    
    function getUserBattleValue(address _userId) view public isValidCaller returns (uint) {
        return users[_userId].battleValue;
    }
    
    function setUserBattleValue(address _userId, uint _battleValue) public  isValidCaller {
        users[_userId].battleValue = _battleValue;
    }
    
    function verifyAmount(address _msgSender, uint _msgValue, uint _amount, bool _useBattleValue) view public isValidCaller {
        User storage user = users[_msgSender];
        require(user.creationTime != 0);

        if (_useBattleValue) {
            require(_msgValue == 0);
            require(user.battleValue >= _amount);
        } else {
            require(_amount == _msgValue);
        }
    }
    
    function addBoostFromTile(Tile _tile, address _attacker, address _defender, Boost memory _boost) pure private {
        if (_tile.claimer == _attacker) {
            require(_boost.attackBoost + _tile.blockValue >= _tile.blockValue); // prevent overflow
            _boost.attackBoost += _tile.blockValue;
            _boost.numAttackBoosts += 1;
        } else if (_tile.claimer == _defender) {
            require(_boost.defendBoost + _tile.blockValue >= _tile.blockValue); // prevent overflow
            _boost.defendBoost += _tile.blockValue;
            _boost.numDefendBoosts += 1;
        }
    }

    function calculateBattleBoost(uint16 _tileId, address _attacker, address _defender) view public isValidCaller returns (uint, uint) {
        uint8 x;
        uint8 y;

        (x, y) = BWUtility.fromTileId(_tileId);

        Boost memory boost = Boost(0, 0, 0, 0);
        // We overflow x, y on purpose here if x or y is 0 or 255 - the map overflows and so should adjacency.
        // Go through all adjacent tiles to (x, y).
        if (y != 255) {
            if (x != 255) {
                addBoostFromTile(tiles[BWUtility.toTileId(x+1, y+1)], _attacker, _defender, boost);
            }
            
            addBoostFromTile(tiles[BWUtility.toTileId(x, y+1)], _attacker, _defender, boost);

            if (x != 0) {
                addBoostFromTile(tiles[BWUtility.toTileId(x-1, y+1)], _attacker, _defender, boost);
            }
        }

        if (x != 255) {
            addBoostFromTile(tiles[BWUtility.toTileId(x+1, y)], _attacker, _defender, boost);
        }

        if (x != 0) {
            addBoostFromTile(tiles[BWUtility.toTileId(x-1, y)], _attacker, _defender, boost);
        }

        if (y != 0) {
            if(x != 255) {
                addBoostFromTile(tiles[BWUtility.toTileId(x+1, y-1)], _attacker, _defender, boost);
            }

            addBoostFromTile(tiles[BWUtility.toTileId(x, y-1)], _attacker, _defender, boost);

            if(x != 0) {
                addBoostFromTile(tiles[BWUtility.toTileId(x-1, y-1)], _attacker, _defender, boost);
            }
        }
        // The benefit of boosts is multiplicative (quadratic):
        // - More boost tiles gives a higher total blockValue (the sum of the adjacent tiles)
        // - More boost tiles give a higher multiple of that total blockValue that can be used (10% per adjacent tie)
        // Example:
        //   A) I boost attack with 1 single tile worth 10 finney
        //      -> Total boost is 10 * 1 / 10 = 1 finney
        //   B) I boost attack with 3 tiles worth 1 finney each
        //      -> Total boost is (1+1+1) * 3 / 10 = 0.9 finney
        //   C) I boost attack with 8 tiles worth 2 finney each
        //      -> Total boost is (2+2+2+2+2+2+2+2) * 8 / 10 = 14.4 finney
        //   D) I boost attack with 3 tiles of 1, 5 and 10 finney respectively
        //      -> Total boost is (ss1+5+10) * 3 / 10 = 4.8 finney
        // This division by 10 can't create fractions since our uint is wei, and we can't have overflow from the multiplication
        // We do allow fractions of finney here since the boosted values aren't stored anywhere, only used for attack rolls and sent in events
        boost.attackBoost = (boost.attackBoost / 10 * boost.numAttackBoosts);
        boost.defendBoost = (boost.defendBoost / 10 * boost.numDefendBoosts);

        return (boost.attackBoost, boost.defendBoost);
    }
    
    function censorUser(address _userAddress, bool _censored) public isValidCaller {
        User storage user = users[_userAddress];
        require(user.creationTime != 0);
        user.censored = _censored;
    }
    
    function deleteTile(uint16 _tileId) public isValidCaller {
        delete tiles[_tileId];
    }
    
    function setSellPrice(uint16 _tileId, uint _sellPrice) public isValidCaller {
        tiles[_tileId].sellPrice = _sellPrice;  //testrpc cannot estimate gas when delete is used.
    }

    function deleteOffer(uint16 _tileId) public isValidCaller {
        tiles[_tileId].sellPrice = 0;  //testrpc cannot estimate gas when delete is used.
    }
}



/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    if (a == 0) {
      return 0;
    }
    c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, 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 Subtracts two numbers, 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 Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}

/**
* Copyright 2018 Block Wars Team
*
*/

interface LocalGameI {
    function getBountyBalance() view external returns (uint);
    function getTimeLeftToNextCollect(address _claimer, uint _latestClaimTime) view external returns (uint);
    function collectBounty(address _msgSender, uint _latestClaimTime, uint _amount) external returns (uint);
}

/*
* @title ERC721 interface
*/
contract ERC721 {
    /// @dev This emits when ownership of any NFT changes by any mechanism.
    ///  This event emits when NFTs are created (`from` == 0) and destroyed
    ///  (`to` == 0). Exception: during contract creation, any number of NFTs
    ///  may be created and assigned without emitting Transfer. At the time of
    ///  any transfer, the approved address for that NFT (if any) is reset to none.
    //event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);

    /// @dev This emits when the approved address for an NFT is changed or
    ///  reaffirmed. The zero address indicates there is no approved address.
    ///  When a Transfer event emits, this also indicates that the approved
    ///  address for that NFT (if any) is reset to none.
    //event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);

    /// @dev This emits when an operator is enabled or disabled for an owner.
    ///  The operator can manage all NFTs of the owner.
    //event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    /// @notice Count all NFTs assigned to an owner
    /// @dev NFTs assigned to the zero address are considered invalid, and this
    ///  function throws for queries about the zero address.
    /// @param _owner An address for whom to query the balance
    /// @return The number of NFTs owned by `_owner`, possibly zero
    function balanceOf(address _owner) external view returns (uint256);

    /// @notice Find the owner of an NFT
    /// @param _tokenId The identifier for an NFT
    /// @dev NFTs assigned to zero address are considered invalid, and queries
    ///  about them do throw.
    /// @return The address of the owner of the NFT
    function ownerOf(uint256 _tokenId) external view returns (address);

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
    ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
    ///  `onERC721Received` on `_to` and throws if the return value is not
    ///  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param data Additional data with no specified format, sent in call to `_to`
    //function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    ///  except this function just sets data to ""
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    ///  THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    //function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

    /// @notice Set or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
    ///  operator of the current owner.
    /// @param _approved The new approved NFT controller
    /// @param _tokenId The NFT to approve
    //function approve(address _approved, uint256 _tokenId) external payable;

    /// @notice Enable or disable approval for a third party ("operator") to manage
    ///  all of `msg.sender`'s assets.
    /// @dev Emits the ApprovalForAll event
    /// @param _operator Address to add to the set of authorized operators.
    /// @param _approved True if the operators is approved, false to revoke approval
    //function setApprovalForAll(address _operator, bool _approved) external;

    /// @notice Get the approved address for a single NFT
    /// @dev Throws if `_tokenId` is not a valid NFT
    /// @param _tokenId The NFT to find the approved address for
    /// @return The approved address for this NFT, or the zero address if there is none
    //function getApproved(uint256 _tokenId) external view returns (address);

    /// @notice Query if an address is an authorized operator for another address
    /// @param _owner The address that owns the NFTs
    /// @param _operator The address that acts on behalf of the owner
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
    //function isApprovedForAll(address _owner, address _operator) external view returns (bool);

    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///  uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    //function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

contract BW { 
    using SafeMath for uint256;
    address public owner;
    BWService private bwService;
    BWData private bwData;
    bool public paused = false;
    uint private BV_TO_BP_FEE = 5; // 5%
    mapping (uint16 => Prize[]) private prizes; // Use mapping instead of array (key would be a unique priceId) - NO (we want to loop all prices)
    
    struct Prize {
        address token; // BWT or CryptoKiities (ERC721)
        uint tokenId; 
        uint startTime; // To be able to add a price before the game starts
        uint hodlPeriod; // Amount of seconds you have to own the tile before being able to claim this price. One block is ~15 sec.
    }

    event PrizeCreated(uint16 tileId,  address token, uint tokenId, uint creationTime, uint startTime, uint hodlPeriod);
    event PrizeRemoved(uint16 tileId, address token, uint tokenId, uint removeTime);
    event PrizeClaimed(address token, uint tokenId);

    // Add price (only BW owner can do this)
    function addPrize(uint16 _tileId, address _token, uint _tokenId, uint _startTime, uint _hodlPeriod) public isOwner {
        //startTime must be same or after block.timestamp
        uint startTime = _startTime;
        if(startTime < block.timestamp) {
            startTime = block.timestamp;
        }
        // we could check if token exists with ownerOf function in interface, 
        // but if any erc721 token doesn't implement the function, this function would revert.
        // also cheaper to not make an interface call
        prizes[_tileId].push(Prize(_token, _tokenId, startTime, _hodlPeriod));
        emit PrizeCreated(_tileId, _token, _tokenId, block.timestamp, startTime, _hodlPeriod);
    }

    // Remove price (only BW owner can do this)
    function removePrize(uint16 _tileId, address _token, uint _tokenId) public isOwner {
        Prize[] storage prizeArr = prizes[_tileId];
        require(prizeArr.length > 0);

        for(uint idx = 0; idx < prizeArr.length; ++idx) {
            if(prizeArr[idx].tokenId == _tokenId && prizeArr[idx].token == _token) {
                delete prizeArr[idx];
                emit PrizeRemoved(_tileId, _token, _tokenId, block.timestamp);
            }
        }
    }

    // Add price (only BW owner can do this)
    function claimPrize(address _tokenAddress, uint16 _tileId) public isNotPaused isNotContractCaller {
        ERC721 token = ERC721(_tokenAddress);
        Prize[] storage prizeArr = prizes[_tileId];
        require(prizeArr.length > 0);
        address claimer;
        uint blockValue;
        uint lastClaimTime;
        uint sellPrice;
        (claimer, blockValue, lastClaimTime, sellPrice) = bwData.getTile(_tileId);
        require(lastClaimTime != 0 && claimer == msg.sender);

        for(uint idx = 0; idx < prizeArr.length; ++idx) {
            if(prizeArr[idx].startTime.add(prizeArr[idx].hodlPeriod) <= block.timestamp
                && lastClaimTime.add(prizeArr[idx].hodlPeriod) <= block.timestamp) {
                uint tokenId = prizeArr[idx].tokenId;
                address tokenOwner = token.ownerOf(tokenId);
                delete prizeArr[idx];
                token.safeTransferFrom(tokenOwner, msg.sender, tokenId); //Will revert if token does not exists
                emit PrizeClaimed(_tokenAddress, tokenId);
            }
        }
    }

    modifier isOwner {
        if (msg.sender != owner) {
            revert();
        }
        _;
    }

    // Checks if entire game (except battle value withdraw) is paused or not.
    modifier isNotPaused {
        if (paused) {
            revert();
        }
        _;
    }

    // Only allow wallets to call this function, not contracts.
    modifier isNotContractCaller {
        require(msg.sender == tx.origin);
        _;
    }

    // All contract event types.
    event UserCreated(address userAddress, bytes32 name, bytes imageUrl, bytes32 tag, bytes32 homeUrl, uint creationTime, address invitedBy);
    event UserCensored(address userAddress, bool isCensored);
    event TransferTileFromOwner(uint16 tileId, address seller, address buyer, uint acceptTime); // Sent when a user buys a tile from another user, by accepting a tile offer
    event UserUpdated(address userAddress, bytes32 name, bytes imageUrl, bytes32 tag, bytes32 homeUrl, uint updateTime);
    event TileRetreated(uint16 tileId, address owner, uint amount, uint newBlockValue, uint retreatTime);
    event BountyCollected(uint tile, address userAddress, uint amount, uint amountCollected, uint collectedTime, uint latestClaimTime);

    // BASIC CONTRACT FUNCTIONS
    constructor(address _bwService, address _bwData) public {
        bwService = BWService(_bwService);
        bwData = BWData(_bwData);
        owner = msg.sender;
    }

    // Can't send funds straight to this contract. Avoid people sending by mistake.
    function () payable public isOwner {

    }

    // Allow a new user to claim one or more previously unclaimed tiles by paying Ether.
    function claimTilesForNewUser(bytes32 _name, bytes _imageUrl, bytes32 _tag, bytes32 _homeUrl, uint16[] _claimedTileIds, address _invitedBy) payable public isNotPaused isNotContractCaller {
        bwData.addUser(msg.sender);
        emit UserCreated(msg.sender, _name, _imageUrl, _tag, _homeUrl, block.timestamp, _invitedBy);
        bwService.storeInitialClaim(msg.sender, _claimedTileIds, msg.value, false);
    }

    // Allow an existing user to claim one or more previously unclaimed tiles by paying Ether.
    function claimTilesForExistingUser(uint16[] _claimedTileIds, uint _claimAmount, bool _useBattleValue) payable public isNotPaused isNotContractCaller {
        bwService.verifyAmount(msg.sender, msg.value, _claimAmount, _useBattleValue);
        bwService.storeInitialClaim(msg.sender, _claimedTileIds, _claimAmount, _useBattleValue);
    }

    // Allow users to change name, image URL, tag and home URL. Not censored status or battle value though.
    function updateUser(bytes32 _name, bytes _imageUrl, bytes32 _tag, bytes32 _homeUrl) public isNotPaused isNotContractCaller {
        require(bwData.hasUser(msg.sender));
        // All the updated values are stored in events only so there's no state to update on the contract here.
        emit UserUpdated(msg.sender, _name, _imageUrl, _tag, _homeUrl, block.timestamp);
    }
    
    // This function fortifies multiple previously claimed tiles in a single transaction.
    // The value assigned to each tile is the msg.value divided by the number of tiles fortified.
    // The msg.value is required to be an even multiple of the number of tiles fortified.
    // Only tiles owned by msg.sender can be fortified.
    function fortifyClaims(uint16[] _claimedTileIds, uint _fortifyAmount, bool _useBattleValue) payable public isNotPaused isNotContractCaller {
        bwService.verifyAmount(msg.sender, msg.value, _fortifyAmount, _useBattleValue);
        bwService.fortifyClaims(msg.sender, _claimedTileIds, _fortifyAmount, _useBattleValue);
    }

    // A new user attacks a tile claimed by someone else, trying to make it theirs through battle.
    function attackTileForNewUser(uint16 _tileId, bytes32 _name, bytes _imageUrl, bytes32 _tag, bytes32 _homeUrl, address _invitedBy) payable public isNotPaused isNotContractCaller {
        bwData.addUser(msg.sender);
        emit UserCreated(msg.sender, _name, _imageUrl, _tag, _homeUrl, block.timestamp, _invitedBy);
        bwService.attackTile(msg.sender, _tileId, msg.value, false);
    }

    // An existing user attacks a tile claimed by someone else, trying to make it theirs through battle.
    function attackTileForExistingUser(uint16 _tileId, uint _attackAmount, bool _useBattleValue) payable public isNotPaused isNotContractCaller {
        bwService.verifyAmount(msg.sender, msg.value, _attackAmount, _useBattleValue);
        bwService.attackTile(msg.sender, _tileId, _attackAmount, _useBattleValue);
    }
    
    // Move "army" = block value from one block to an adjacent block. Moving ALL value equates giving up ownership of the source tile.
    function moveBlockValue(uint8 _xSource, uint8 _ySource, uint8 _xDest, uint8 _yDest, uint _moveAmount) public isNotPaused isNotContractCaller {
        require(_moveAmount > 0);
        bwService.moveBlockValue(msg.sender, _xSource, _ySource, _xDest, _yDest, _moveAmount);
    }

    // Allow users to withdraw battle value in Ether.
    function withdrawBattleValue(uint _battleValueInWei) public isNotContractCaller {
        require(_battleValueInWei > 0);
        uint amountToWithdraw = bwService.withdrawBattleValue(msg.sender, _battleValueInWei);
        msg.sender.transfer(amountToWithdraw);
    }

    // Transfer block value to battle points for free 
    function transferBlockValueToBattleValue(uint16 _tileId, uint _amount) public isNotContractCaller {
        require(_amount > 0);
        address claimer;
        uint blockValue;
        (claimer, blockValue) = bwData.getTileClaimerAndBlockValue(_tileId);
        require(claimer == msg.sender);
        uint newBlockValue = blockValue.sub(_amount);
        // Must transfer the entire block value or leave at least 5
        require(newBlockValue == 0 || newBlockValue >= 5 finney);
        if(newBlockValue == 0) {
            bwData.deleteTile(_tileId);
        } else {
            bwData.updateTileBlockValue(_tileId, newBlockValue);
            bwData.deleteOffer(_tileId); // Offer invalid since block value has changed
        }
        
        uint fee = _amount.mul(BV_TO_BP_FEE).div(100);
        uint userAmount = _amount.sub(fee);
        uint feeBalance = bwData.getFeeBalance();
        feeBalance = feeBalance.add(fee);
        bwData.setFeeBalance(feeBalance);

        bwService.addUserBattleValue(msg.sender, userAmount);
        bwService.subGlobalBlockValueBalance(_amount);
        emit TileRetreated(_tileId, msg.sender, _amount, newBlockValue, block.timestamp);
    }

    // -------- LOCAL GAME FUNCTIONS ----------

    function getLocalBountyBalance(uint16 _tileId) view public isNotContractCaller returns (uint) {
        address localGameAddress = bwService.getLocalGame(_tileId);
        require(localGameAddress != 0);
        LocalGameI localGame = LocalGameI(localGameAddress);
        return localGame.getBountyBalance();
    }

    function getTimeLeftToNextLocalBountyCollect(uint16 _tileId) view public isNotContractCaller returns (uint) {
        address localGameAddress = bwService.getLocalGame(_tileId);
        require(localGameAddress != 0);
        LocalGameI localGame = LocalGameI(localGameAddress);
        address claimer;
        uint blockValue;
        uint latestClaimTime;
        uint sellPrice;
        (claimer, blockValue, latestClaimTime, sellPrice) = bwData.getTile(_tileId);
        return localGame.getTimeLeftToNextCollect(claimer, latestClaimTime);
    }

    function collectLocalBounty(uint16 _tileId, uint _amount) public isNotContractCaller {
        address localGameAddress = bwService.getLocalGame(_tileId);
        require(localGameAddress != 0);
        address claimer;
        uint blockValue;
        uint latestClaimTime;
        uint sellPrice;
        (claimer, blockValue, latestClaimTime, sellPrice) = bwData.getTile(_tileId);
        require(latestClaimTime != 0 && claimer == msg.sender);
        
        LocalGameI localGame = LocalGameI(localGameAddress);
        uint amountCollected = localGame.collectBounty(msg.sender, latestClaimTime, _amount);
        emit BountyCollected(_tileId, msg.sender, _amount, amountCollected, block.timestamp, latestClaimTime);
    }

    // -------- OWNER-ONLY FUNCTIONS ----------

    // Only used by owner for raffle. Owner need name, address and picture from user.
    // These users can then be given tiles by owner using transferTileFromOwner.
    function createNewUser(bytes32 _name, bytes _imageUrl, bytes32 _tag, bytes32 _homeUrl, address _user) public isOwner {
        bwData.addUser(_user);
        emit UserCreated(_user, _name, _imageUrl, _tag, _homeUrl, block.timestamp, msg.sender); //check on client if invitedBy is owner.
    }

    // Allow updating censored status. Owner only. In case someone uploads offensive content.
    // The contract owners reserve the right to apply censorship. This will mean that the
    // name, tag or URL images might not be displayed for a censored user.
    function censorUser(address _userAddress, bool _censored) public isOwner {
        bwData.censorUser(_userAddress, _censored);
        emit UserCensored(_userAddress, _censored);
    }

    // Pause the entire game, but let users keep withdrawing battle value
    function setPaused(bool _paused) public isOwner {
        paused = _paused;
    }

    function kill() public isOwner {
        selfdestruct(owner);
    }
    
    function withdrawFee() public isOwner {
        uint balance = address(this).balance;
        uint amountToWithdraw = bwData.getFeeBalance();

        if (balance < amountToWithdraw) { // Should never happen, but paranoia
            amountToWithdraw = balance;
        }
        bwData.setFeeBalance(0);

        owner.transfer(amountToWithdraw);
    }

    function getFee() view public isOwner returns (uint) {
        return bwData.getFeeBalance();
    }

    function setBvToBpFee(uint _feePercentage) public isOwner {
        BV_TO_BP_FEE = _feePercentage;
    }

    function depositBattleValue(address _user) payable public isOwner {
        require(msg.value % 1 finney == 0); // Must be divisible by 1 finney
        bwService.addUserBattleValue(_user, msg.value);
    }

    // The owner can transfer ownership of own tiles to other users, as prizes in competitions.
    function transferTileFromOwner(uint16[] _tileIds, address _newOwner) public isOwner {
        for(uint i = 0; i < _tileIds.length; ++i) {
            uint16 tileId = _tileIds[i];
            address claimer = bwData.getCurrentClaimerForTile(tileId);
            require(claimer == owner);
            bwData.setClaimerForTile(tileId, _newOwner);
            
            emit TransferTileFromOwner(tileId, _newOwner, msg.sender, block.timestamp);
        }
    }

    // Allow us to transfer out airdropped tokens if we ever receive any
    function transferTokens(address _tokenAddress, address _recipient) public isOwner {
        ERC20I token = ERC20I(_tokenAddress);
        require(token.transfer(_recipient, token.balanceOf(this)));
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"_claimedTileIds","type":"uint16[]"},{"name":"_claimAmount","type":"uint256"},{"name":"_useBattleValue","type":"bool"}],"name":"claimTilesForExistingUser","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_tileId","type":"uint16"},{"name":"_token","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_startTime","type":"uint256"},{"name":"_hodlPeriod","type":"uint256"}],"name":"addPrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tileId","type":"uint16"},{"name":"_name","type":"bytes32"},{"name":"_imageUrl","type":"bytes"},{"name":"_tag","type":"bytes32"},{"name":"_homeUrl","type":"bytes32"},{"name":"_invitedBy","type":"address"}],"name":"attackTileForNewUser","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_tileId","type":"uint16"},{"name":"_amount","type":"uint256"}],"name":"collectLocalBounty","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tileId","type":"uint16"}],"name":"getLocalBountyBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_feePercentage","type":"uint256"}],"name":"setBvToBpFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenAddress","type":"address"},{"name":"_recipient","type":"address"}],"name":"transferTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tileId","type":"uint16"},{"name":"_amount","type":"uint256"}],"name":"transferBlockValueToBattleValue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_imageUrl","type":"bytes"},{"name":"_tag","type":"bytes32"},{"name":"_homeUrl","type":"bytes32"}],"name":"updateUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_xSource","type":"uint8"},{"name":"_ySource","type":"uint8"},{"name":"_xDest","type":"uint8"},{"name":"_yDest","type":"uint8"},{"name":"_moveAmount","type":"uint256"}],"name":"moveBlockValue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenAddress","type":"address"},{"name":"_tileId","type":"uint16"}],"name":"claimPrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tileId","type":"uint16"},{"name":"_attackAmount","type":"uint256"},{"name":"_useBattleValue","type":"bool"}],"name":"attackTileForExistingUser","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_tileId","type":"uint16"},{"name":"_token","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"removePrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_imageUrl","type":"bytes"},{"name":"_tag","type":"bytes32"},{"name":"_homeUrl","type":"bytes32"},{"name":"_user","type":"address"}],"name":"createNewUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_imageUrl","type":"bytes"},{"name":"_tag","type":"bytes32"},{"name":"_homeUrl","type":"bytes32"},{"name":"_claimedTileIds","type":"uint16[]"},{"name":"_invitedBy","type":"address"}],"name":"claimTilesForNewUser","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_tileId","type":"uint16"}],"name":"getTimeLeftToNextLocalBountyCollect","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tileIds","type":"uint16[]"},{"name":"_newOwner","type":"address"}],"name":"transferTileFromOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_userAddress","type":"address"},{"name":"_censored","type":"bool"}],"name":"censorUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_user","type":"address"}],"name":"depositBattleValue","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_claimedTileIds","type":"uint16[]"},{"name":"_fortifyAmount","type":"uint256"},{"name":"_useBattleValue","type":"bool"}],"name":"fortifyClaims","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_battleValueInWei","type":"uint256"}],"name":"withdrawBattleValue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_bwService","type":"address"},{"name":"_bwData","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tileId","type":"uint16"},{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"creationTime","type":"uint256"},{"indexed":false,"name":"startTime","type":"uint256"},{"indexed":false,"name":"hodlPeriod","type":"uint256"}],"name":"PrizeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tileId","type":"uint16"},{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"removeTime","type":"uint256"}],"name":"PrizeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"PrizeClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"userAddress","type":"address"},{"indexed":false,"name":"name","type":"bytes32"},{"indexed":false,"name":"imageUrl","type":"bytes"},{"indexed":false,"name":"tag","type":"bytes32"},{"indexed":false,"name":"homeUrl","type":"bytes32"},{"indexed":false,"name":"creationTime","type":"uint256"},{"indexed":false,"name":"invitedBy","type":"address"}],"name":"UserCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"userAddress","type":"address"},{"indexed":false,"name":"isCensored","type":"bool"}],"name":"UserCensored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tileId","type":"uint16"},{"indexed":false,"name":"seller","type":"address"},{"indexed":false,"name":"buyer","type":"address"},{"indexed":false,"name":"acceptTime","type":"uint256"}],"name":"TransferTileFromOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"userAddress","type":"address"},{"indexed":false,"name":"name","type":"bytes32"},{"indexed":false,"name":"imageUrl","type":"bytes"},{"indexed":false,"name":"tag","type":"bytes32"},{"indexed":false,"name":"homeUrl","type":"bytes32"},{"indexed":false,"name":"updateTime","type":"uint256"}],"name":"UserUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tileId","type":"uint16"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"newBlockValue","type":"uint256"},{"indexed":false,"name":"retreatTime","type":"uint256"}],"name":"TileRetreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tile","type":"uint256"},{"indexed":false,"name":"userAddress","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"amountCollected","type":"uint256"},{"indexed":false,"name":"collectedTime","type":"uint256"},{"indexed":false,"name":"latestClaimTime","type":"uint256"}],"name":"BountyCollected","type":"event"}]

60806040526000600260146101000a81548160ff021916908315150217905550600560035534801561003057600080fd5b50604051604080614ae3833981018060405281019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506149b3806101306000396000f30060806040526004361061015f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063021ea45e146101bc578063124c27a91461022b57806316c38b3c1461029a578063292a9873146102c95780632ad2ae2e1461037d57806341c0e1b5146103b85780634fb0d95e146103cf578063531ef079146104145780635c975abb146104415780636a092e79146104705780637746167f146104d35780637a0e2d1a1461050e5780638beb9f12146105a15780638da5cb5b14610602578063a00545b214610659578063ad0a6cc3146106aa578063ae7fa597146106e4578063b01800f81461073f578063b607ea45146107f2578063c022ef43146108db578063c0338a0c14610920578063c26181e0146109a6578063ced72f87146109f5578063e3e5075c14610a20578063e430930714610a56578063e941fa7814610ac5578063f53773dc14610adc575b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101ba57600080fd5b005b6102296004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190929190803515159060200190929190505050610b09565b005b34801561023757600080fd5b50610298600480360381019080803561ffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050610d85565b005b3480156102a657600080fd5b506102c7600480360381019080803515159060200190929190505050610f72565b005b61037b600480360381019080803561ffff1690602001909291908035600019169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080356000191690602001909291908035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fea565b005b34801561038957600080fd5b506103b6600480360381019080803561ffff16906020019092919080359060200190929190505050611351565b005b3480156103c457600080fd5b506103cd611760565b005b3480156103db57600080fd5b506103fe600480360381019080803561ffff1690602001909291905050506117f5565b6040518082815260200191505060405180910390f35b34801561042057600080fd5b5061043f600480360381019080803590602001909291905050506119db565b005b34801561044d57600080fd5b50610456611a40565b604051808215151515815260200191505060405180910390f35b34801561047c57600080fd5b506104d1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a53565b005b3480156104df57600080fd5b5061050c600480360381019080803561ffff16906020019092919080359060200190929190505050611c76565b005b34801561051a57600080fd5b5061059f6004803603810190808035600019169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080356000191690602001909291908035600019169060200190929190505050612422565b005b3480156105ad57600080fd5b50610600600480360381019080803560ff169060200190929190803560ff169060200190929190803560ff169060200190929190803560ff16906020019092919080359060200190929190505050612687565b005b34801561060e57600080fd5b50610617612806565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561066557600080fd5b506106a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803561ffff16906020019092919050505061282b565b005b6106e2600480360381019080803561ffff16906020019092919080359060200190929190803515159060200190929190505050612d4f565b005b3480156106f057600080fd5b5061073d600480360381019080803561ffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612f92565b005b34801561074b57600080fd5b506107f06004803603810190808035600019169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080356000191690602001909291908035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131c2565b005b6108d96004803603810190808035600019169060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192908035600019169060200190929190803560001916906020019092919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613435565b005b3480156108e757600080fd5b5061090a600480360381019080803561ffff1690602001909291905050506137d5565b6040518082815260200191505060405180910390f35b34801561092c57600080fd5b506109a460048036038101908080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b06565b005b3480156109b257600080fd5b506109f3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050613e65565b005b348015610a0157600080fd5b50610a0a614014565b6040518082815260200191505060405180910390f35b610a54600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614137565b005b610ac36004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190929190803515159060200190929190505050614293565b005b348015610ad157600080fd5b50610ada61450f565b005b348015610ae857600080fd5b50610b076004803603810190808035906020019092919050505061476c565b005b600260149054906101000a900460ff1615610b2357600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b5d57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332214874333485856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182151515158152602001945050505050600060405180830381600087803b158015610c3657600080fd5b505af1158015610c4a573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4212e93338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200184815260200183151515158152602001828103825285818151815260200191508051906020019060200280838360005b83811015610d40578082015181840152602081019050610d25565b5050505090500195505050505050600060405180830381600087803b158015610d6857600080fd5b505af1158015610d7c573d6000803e3d6000fd5b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de257600080fd5b82905042811015610df1574290505b600460008761ffff1661ffff1681526020019081526020016000206080604051908101604052808773ffffffffffffffffffffffffffffffffffffffff168152602001868152602001838152602001848152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301555050507f95b8377701688cfdeae0067b4ef836749389a319ef3951dfc9b9a0662704e11e868686428587604051808761ffff1661ffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a1505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610fcd57600080fd5b80600260146101000a81548160ff02191690831515021790555050565b600260149054906101000a900460ff161561100457600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561103e57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663421b2d8b336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b505050507ff1e08403e8c6577dc32cd66518e15d1663f8bffdd495f968daa71684b278e90833868686864287604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001876000191660001916815260200180602001866000191660001916815260200185600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b8381101561120f5780820151818401526020810190506111f4565b50505050905090810190601f16801561123c5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166372852fe533883460006040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018461ffff1661ffff16815260200183815260200182151515158152602001945050505050600060405180830381600087803b15801561133157600080fd5b505af1158015611345573d6000803e3d6000fd5b50505050505050505050565b60008060008060008060003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561139657600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631ba3afd38a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b15801561142f57600080fd5b505af1158015611443573d6000803e3d6000fd5b505050506040513d602081101561145957600080fd5b8101908080519060200190929190505050965060008773ffffffffffffffffffffffffffffffffffffffff161415151561149257600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ac2c8bb58a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050608060405180830381600087803b15801561152b57600080fd5b505af115801561153f573d6000803e3d6000fd5b505050506040513d608081101561155557600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505080965081975082985083995050505050600084141580156115d057503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b15156115db57600080fd5b8691508173ffffffffffffffffffffffffffffffffffffffff16630f88f1a533868b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050506040513d60208110156116b357600080fd5b810190808051906020019092919050505090507f9579a77b52045388aad0d9a4d23dac16c17649936242f724ccd8e0984fce495e89338a844289604051808761ffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a1505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156117bb57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b60008060003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561183457600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631ba3afd3856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b1580156118cd57600080fd5b505af11580156118e1573d6000803e3d6000fd5b505050506040513d60208110156118f757600080fd5b8101908080519060200190929190505050915060008273ffffffffffffffffffffffffffffffffffffffff161415151561193057600080fd5b8190508073ffffffffffffffffffffffffffffffffffffffff166372067d496040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b505050506040513d60208110156119c157600080fd5b810190808051906020019092919050505092505050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a3657600080fd5b8060038190555050565b600260149054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611ab057600080fd5b8290508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb838373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611b6b57600080fd5b505af1158015611b7f573d6000803e3d6000fd5b505050506040513d6020811015611b9557600080fd5b81019080805190602001909291905050506040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611c2b57600080fd5b505af1158015611c3f573d6000803e3d6000fd5b505050506040513d6020811015611c5557600080fd5b81019080805190602001909291905050501515611c7157600080fd5b505050565b6000806000806000803273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611cb957600080fd5b600087111515611cc857600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357cc5941896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff1681526020019150506040805180830381600087803b158015611d6057600080fd5b505af1158015611d74573d6000803e3d6000fd5b505050506040513d6040811015611d8a57600080fd5b81019080805190602001909291908051906020019092919050505080965081975050503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141515611de757600080fd5b611dfa878661490490919063ffffffff16565b93506000841480611e1257506611c37937e080008410155b1515611e1d57600080fd5b6000841415611edc57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4010db0896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050600060405180830381600087803b158015611ebf57600080fd5b505af1158015611ed3573d6000803e3d6000fd5b50505050612047565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639ea6954189866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808361ffff1661ffff16815260200182815260200192505050600060405180830381600087803b158015611f7d57600080fd5b505af1158015611f91573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bff10815896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050600060405180830381600087803b15801561202e57600080fd5b505af1158015612042573d6000803e3d6000fd5b505050505b61206f60646120616003548a61491d90919063ffffffff16565b61495590919063ffffffff16565b9250612084838861490490919063ffffffff16565b9150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4c30ceb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561210c57600080fd5b505af1158015612120573d6000803e3d6000fd5b505050506040513d602081101561213657600080fd5b8101908080519060200190929190505050905061215c838261496b90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638580eb2f826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156121ef57600080fd5b505af1158015612203573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663330ae7b333846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156122cc57600080fd5b505af11580156122e0573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639f08fc38886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561237557600080fd5b505af1158015612389573d6000803e3d6000fd5b505050507febf382a69d356c17e7446397e5c296bfd479081e62e71e9b7e157db51b379a068833898742604051808661ffff1661ffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019550505050505060405180910390a15050505050505050565b600260149054906101000a900460ff161561243c57600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561247657600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a6c4ec0e336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561253357600080fd5b505af1158015612547573d6000803e3d6000fd5b505050506040513d602081101561255d57600080fd5b8101908080519060200190929190505050151561257957600080fd5b7ff1d9d3a279c958c3eafa779ad7a67dde66017e5dfc1989b5cf249e7b58661d12338585858542604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186600019166000191681526020018060200185600019166000191681526020018460001916600019168152602001838152602001828103825286818151815260200191508051906020019080838360005b83811015612642578082015181840152602081019050612627565b50505050905090810190601f16801561266f5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a150505050565b600260149054906101000a900460ff16156126a157600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156126db57600080fd5b6000811115156126ea57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fe562ee63387878787876040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018660ff1660ff1681526020018560ff1660ff1681526020018460ff1660ff1681526020018360ff1660ff1681526020018281526020019650505050505050600060405180830381600087803b1580156127e757600080fd5b505af11580156127fb573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000600260149054906101000a900460ff161561285357600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561288d57600080fd5b8a9850600460008b61ffff1661ffff1681526020019081526020016000209750600088805490501115156128c057600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ac2c8bb58b6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050608060405180830381600087803b15801561295957600080fd5b505af115801561296d573d6000803e3d6000fd5b505050506040513d608081101561298357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050809750819850829950839a5050505050600085141580156129fe57503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16145b1515612a0957600080fd5b600092505b8780549050831015612d425742612a6c8985815481101515612a2c57fe5b9060005260206000209060040201600301548a86815481101515612a4c57fe5b90600052602060002090600402016002015461496b90919063ffffffff16565b11158015612aab575042612aa88985815481101515612a8757fe5b9060005260206000209060040201600301548761496b90919063ffffffff16565b11155b15612d37578783815481101515612abe57fe5b90600052602060002090600402016001015491508873ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015612b4157600080fd5b505af1158015612b55573d6000803e3d6000fd5b505050506040513d6020811015612b6b57600080fd5b810190808051906020019092919050505090508783815481101515612b8c57fe5b9060005260206000209060040201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160009055600382016000905550508873ffffffffffffffffffffffffffffffffffffffff166342842e0e8233856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015612cb357600080fd5b505af1158015612cc7573d6000803e3d6000fd5b505050507f95681e512bc0fe659e195e06c283eada494316f3d801213e48e7101af92bf7708b83604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b826001019250612a0e565b5050505050505050505050565b600260149054906101000a900460ff1615612d6957600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612da357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332214874333485856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182151515158152602001945050505050600060405180830381600087803b158015612e7c57600080fd5b505af1158015612e90573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166372852fe5338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018461ffff1661ffff16815260200183815260200182151515158152602001945050505050600060405180830381600087803b158015612f7557600080fd5b505af1158015612f89573d6000803e3d6000fd5b50505050505050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612ff057600080fd5b600460008661ffff1661ffff16815260200190815260200160002091506000828054905011151561302057600080fd5b600090505b81805490508110156131bb5782828281548110151561304057fe5b9060005260206000209060040201600101541480156130c957508373ffffffffffffffffffffffffffffffffffffffff16828281548110151561307f57fe5b906000526020600020906004020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156131b05781818154811015156130dc57fe5b9060005260206000209060040201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160009055600382016000905550507f46cc5a4ac65c49e4620e528287cf1c349db9515832147e43a7532aa93a8dfdd485858542604051808561ffff1661ffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a15b806001019050613025565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561321d57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663421b2d8b826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156132da57600080fd5b505af11580156132ee573d6000803e3d6000fd5b505050507ff1e08403e8c6577dc32cd66518e15d1663f8bffdd495f968daa71684b278e90881868686864233604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001876000191660001916815260200180602001866000191660001916815260200185600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b838110156133ee5780820151818401526020810190506133d3565b50505050905090810190601f16801561341b5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a15050505050565b600260149054906101000a900460ff161561344f57600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561348957600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663421b2d8b336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561354657600080fd5b505af115801561355a573d6000803e3d6000fd5b505050507ff1e08403e8c6577dc32cd66518e15d1663f8bffdd495f968daa71684b278e90833878787874287604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001876000191660001916815260200180602001866000191660001916815260200185600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b8381101561365a57808201518184015260208101905061363f565b50505050905090810190601f1680156136875780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4212e9333843460006040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200184815260200183151515158152602001828103825285818151815260200191508051906020019060200280838360005b8381101561378d578082015181840152602081019050613772565b5050505090500195505050505050600060405180830381600087803b1580156137b557600080fd5b505af11580156137c9573d6000803e3d6000fd5b50505050505050505050565b60008060008060008060003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561381a57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631ba3afd3896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b1580156138b357600080fd5b505af11580156138c7573d6000803e3d6000fd5b505050506040513d60208110156138dd57600080fd5b8101908080519060200190929190505050955060008673ffffffffffffffffffffffffffffffffffffffff161415151561391657600080fd5b859450600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ac2c8bb5896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050608060405180830381600087803b1580156139b257600080fd5b505af11580156139c6573d6000803e3d6000fd5b505050506040513d60808110156139dc57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050809450819550829650839750505050508473ffffffffffffffffffffffffffffffffffffffff166380a1ba6a85846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015613abe57600080fd5b505af1158015613ad2573d6000803e3d6000fd5b505050506040513d6020811015613ae857600080fd5b81019080805190602001909291905050509650505050505050919050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613b6657600080fd5b600092505b8451831015613e5e578483815181101515613b8257fe5b906020019060200201519150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663aae40ddc836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b158015613c2757600080fd5b505af1158015613c3b573d6000803e3d6000fd5b505050506040513d6020811015613c5157600080fd5b810190808051906020019092919050505090506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515613cbf57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632f54a61e83866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808361ffff1661ffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015613d8c57600080fd5b505af1158015613da0573d6000803e3d6000fd5b505050507f0936305ed8fb00934042531a7c9b5ac31f245e8891500f7ea7192f3912e2530f82853342604051808561ffff1661ffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390a1826001019250613b6b565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613ec057600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c26181e083836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018215151515815260200192505050600060405180830381600087803b158015613f8957600080fd5b505af1158015613f9d573d6000803e3d6000fd5b505050507fc661a5cc93e5e19e1839d5e38cc38bd2d6397f2e1396b1e167894642e8b44ce98282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a15050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561407157600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4c30ceb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156140f757600080fd5b505af115801561410b573d6000803e3d6000fd5b505050506040513d602081101561412157600080fd5b8101908080519060200190929190505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561419257600080fd5b600066038d7ea4c68000348115156141a657fe5b061415156141b357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663330ae7b382346040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561427857600080fd5b505af115801561428c573d6000803e3d6000fd5b5050505050565b600260149054906101000a900460ff16156142ad57600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156142e757600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332214874333485856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182151515158152602001945050505050600060405180830381600087803b1580156143c057600080fd5b505af11580156143d4573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c27bc7b2338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200184815260200183151515158152602001828103825285818151815260200191508051906020019060200280838360005b838110156144ca5780820151818401526020810190506144af565b5050505090500195505050505050600060405180830381600087803b1580156144f257600080fd5b505af1158015614506573d6000803e3d6000fd5b50505050505050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561456d57600080fd5b3073ffffffffffffffffffffffffffffffffffffffff16319150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4c30ceb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561460d57600080fd5b505af1158015614621573d6000803e3d6000fd5b505050506040513d602081101561463757600080fd5b8101908080519060200190929190505050905080821015614656578190505b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638580eb2f60006040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156146e857600080fd5b505af11580156146fc573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015614767573d6000803e3d6000fd5b505050565b60003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156147a857600080fd5b6000821115156147b757600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166311bb20da33846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561487c57600080fd5b505af1158015614890573d6000803e3d6000fd5b505050506040513d60208110156148a657600080fd5b810190808051906020019092919050505090503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156148ff573d6000803e3d6000fd5b505050565b600082821115151561491257fe5b818303905092915050565b600080831415614930576000905061494f565b818302905081838281151561494157fe5b0414151561494b57fe5b8090505b92915050565b6000818381151561496257fe5b04905092915050565b6000818301905082811015151561497e57fe5b809050929150505600a165627a7a72305820ee7f70821b09947c36beeab5b3a2676c1d335f625776157a3245d04b16c860220029000000000000000000000000168848b7ec6c61bd452ee6e74ae85b07cc3b8d1700000000000000000000000053d34d53a692e6352565909acda5af9145f11bf6

Deployed Bytecode

0x60806040526004361061015f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063021ea45e146101bc578063124c27a91461022b57806316c38b3c1461029a578063292a9873146102c95780632ad2ae2e1461037d57806341c0e1b5146103b85780634fb0d95e146103cf578063531ef079146104145780635c975abb146104415780636a092e79146104705780637746167f146104d35780637a0e2d1a1461050e5780638beb9f12146105a15780638da5cb5b14610602578063a00545b214610659578063ad0a6cc3146106aa578063ae7fa597146106e4578063b01800f81461073f578063b607ea45146107f2578063c022ef43146108db578063c0338a0c14610920578063c26181e0146109a6578063ced72f87146109f5578063e3e5075c14610a20578063e430930714610a56578063e941fa7814610ac5578063f53773dc14610adc575b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101ba57600080fd5b005b6102296004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190929190803515159060200190929190505050610b09565b005b34801561023757600080fd5b50610298600480360381019080803561ffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050610d85565b005b3480156102a657600080fd5b506102c7600480360381019080803515159060200190929190505050610f72565b005b61037b600480360381019080803561ffff1690602001909291908035600019169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080356000191690602001909291908035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fea565b005b34801561038957600080fd5b506103b6600480360381019080803561ffff16906020019092919080359060200190929190505050611351565b005b3480156103c457600080fd5b506103cd611760565b005b3480156103db57600080fd5b506103fe600480360381019080803561ffff1690602001909291905050506117f5565b6040518082815260200191505060405180910390f35b34801561042057600080fd5b5061043f600480360381019080803590602001909291905050506119db565b005b34801561044d57600080fd5b50610456611a40565b604051808215151515815260200191505060405180910390f35b34801561047c57600080fd5b506104d1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a53565b005b3480156104df57600080fd5b5061050c600480360381019080803561ffff16906020019092919080359060200190929190505050611c76565b005b34801561051a57600080fd5b5061059f6004803603810190808035600019169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080356000191690602001909291908035600019169060200190929190505050612422565b005b3480156105ad57600080fd5b50610600600480360381019080803560ff169060200190929190803560ff169060200190929190803560ff169060200190929190803560ff16906020019092919080359060200190929190505050612687565b005b34801561060e57600080fd5b50610617612806565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561066557600080fd5b506106a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803561ffff16906020019092919050505061282b565b005b6106e2600480360381019080803561ffff16906020019092919080359060200190929190803515159060200190929190505050612d4f565b005b3480156106f057600080fd5b5061073d600480360381019080803561ffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612f92565b005b34801561074b57600080fd5b506107f06004803603810190808035600019169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080356000191690602001909291908035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131c2565b005b6108d96004803603810190808035600019169060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192908035600019169060200190929190803560001916906020019092919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613435565b005b3480156108e757600080fd5b5061090a600480360381019080803561ffff1690602001909291905050506137d5565b6040518082815260200191505060405180910390f35b34801561092c57600080fd5b506109a460048036038101908080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b06565b005b3480156109b257600080fd5b506109f3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050613e65565b005b348015610a0157600080fd5b50610a0a614014565b6040518082815260200191505060405180910390f35b610a54600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614137565b005b610ac36004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190929190803515159060200190929190505050614293565b005b348015610ad157600080fd5b50610ada61450f565b005b348015610ae857600080fd5b50610b076004803603810190808035906020019092919050505061476c565b005b600260149054906101000a900460ff1615610b2357600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b5d57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332214874333485856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182151515158152602001945050505050600060405180830381600087803b158015610c3657600080fd5b505af1158015610c4a573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4212e93338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200184815260200183151515158152602001828103825285818151815260200191508051906020019060200280838360005b83811015610d40578082015181840152602081019050610d25565b5050505090500195505050505050600060405180830381600087803b158015610d6857600080fd5b505af1158015610d7c573d6000803e3d6000fd5b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de257600080fd5b82905042811015610df1574290505b600460008761ffff1661ffff1681526020019081526020016000206080604051908101604052808773ffffffffffffffffffffffffffffffffffffffff168152602001868152602001838152602001848152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301555050507f95b8377701688cfdeae0067b4ef836749389a319ef3951dfc9b9a0662704e11e868686428587604051808761ffff1661ffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a1505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610fcd57600080fd5b80600260146101000a81548160ff02191690831515021790555050565b600260149054906101000a900460ff161561100457600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561103e57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663421b2d8b336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b505050507ff1e08403e8c6577dc32cd66518e15d1663f8bffdd495f968daa71684b278e90833868686864287604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001876000191660001916815260200180602001866000191660001916815260200185600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b8381101561120f5780820151818401526020810190506111f4565b50505050905090810190601f16801561123c5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166372852fe533883460006040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018461ffff1661ffff16815260200183815260200182151515158152602001945050505050600060405180830381600087803b15801561133157600080fd5b505af1158015611345573d6000803e3d6000fd5b50505050505050505050565b60008060008060008060003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561139657600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631ba3afd38a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b15801561142f57600080fd5b505af1158015611443573d6000803e3d6000fd5b505050506040513d602081101561145957600080fd5b8101908080519060200190929190505050965060008773ffffffffffffffffffffffffffffffffffffffff161415151561149257600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ac2c8bb58a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050608060405180830381600087803b15801561152b57600080fd5b505af115801561153f573d6000803e3d6000fd5b505050506040513d608081101561155557600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505080965081975082985083995050505050600084141580156115d057503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b15156115db57600080fd5b8691508173ffffffffffffffffffffffffffffffffffffffff16630f88f1a533868b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050506040513d60208110156116b357600080fd5b810190808051906020019092919050505090507f9579a77b52045388aad0d9a4d23dac16c17649936242f724ccd8e0984fce495e89338a844289604051808761ffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a1505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156117bb57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b60008060003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561183457600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631ba3afd3856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b1580156118cd57600080fd5b505af11580156118e1573d6000803e3d6000fd5b505050506040513d60208110156118f757600080fd5b8101908080519060200190929190505050915060008273ffffffffffffffffffffffffffffffffffffffff161415151561193057600080fd5b8190508073ffffffffffffffffffffffffffffffffffffffff166372067d496040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b505050506040513d60208110156119c157600080fd5b810190808051906020019092919050505092505050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a3657600080fd5b8060038190555050565b600260149054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611ab057600080fd5b8290508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb838373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611b6b57600080fd5b505af1158015611b7f573d6000803e3d6000fd5b505050506040513d6020811015611b9557600080fd5b81019080805190602001909291905050506040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611c2b57600080fd5b505af1158015611c3f573d6000803e3d6000fd5b505050506040513d6020811015611c5557600080fd5b81019080805190602001909291905050501515611c7157600080fd5b505050565b6000806000806000803273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611cb957600080fd5b600087111515611cc857600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357cc5941896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff1681526020019150506040805180830381600087803b158015611d6057600080fd5b505af1158015611d74573d6000803e3d6000fd5b505050506040513d6040811015611d8a57600080fd5b81019080805190602001909291908051906020019092919050505080965081975050503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141515611de757600080fd5b611dfa878661490490919063ffffffff16565b93506000841480611e1257506611c37937e080008410155b1515611e1d57600080fd5b6000841415611edc57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4010db0896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050600060405180830381600087803b158015611ebf57600080fd5b505af1158015611ed3573d6000803e3d6000fd5b50505050612047565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639ea6954189866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808361ffff1661ffff16815260200182815260200192505050600060405180830381600087803b158015611f7d57600080fd5b505af1158015611f91573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bff10815896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050600060405180830381600087803b15801561202e57600080fd5b505af1158015612042573d6000803e3d6000fd5b505050505b61206f60646120616003548a61491d90919063ffffffff16565b61495590919063ffffffff16565b9250612084838861490490919063ffffffff16565b9150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4c30ceb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561210c57600080fd5b505af1158015612120573d6000803e3d6000fd5b505050506040513d602081101561213657600080fd5b8101908080519060200190929190505050905061215c838261496b90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638580eb2f826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156121ef57600080fd5b505af1158015612203573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663330ae7b333846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156122cc57600080fd5b505af11580156122e0573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639f08fc38886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561237557600080fd5b505af1158015612389573d6000803e3d6000fd5b505050507febf382a69d356c17e7446397e5c296bfd479081e62e71e9b7e157db51b379a068833898742604051808661ffff1661ffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019550505050505060405180910390a15050505050505050565b600260149054906101000a900460ff161561243c57600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561247657600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a6c4ec0e336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561253357600080fd5b505af1158015612547573d6000803e3d6000fd5b505050506040513d602081101561255d57600080fd5b8101908080519060200190929190505050151561257957600080fd5b7ff1d9d3a279c958c3eafa779ad7a67dde66017e5dfc1989b5cf249e7b58661d12338585858542604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186600019166000191681526020018060200185600019166000191681526020018460001916600019168152602001838152602001828103825286818151815260200191508051906020019080838360005b83811015612642578082015181840152602081019050612627565b50505050905090810190601f16801561266f5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a150505050565b600260149054906101000a900460ff16156126a157600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156126db57600080fd5b6000811115156126ea57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fe562ee63387878787876040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018660ff1660ff1681526020018560ff1660ff1681526020018460ff1660ff1681526020018360ff1660ff1681526020018281526020019650505050505050600060405180830381600087803b1580156127e757600080fd5b505af11580156127fb573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000600260149054906101000a900460ff161561285357600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561288d57600080fd5b8a9850600460008b61ffff1661ffff1681526020019081526020016000209750600088805490501115156128c057600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ac2c8bb58b6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050608060405180830381600087803b15801561295957600080fd5b505af115801561296d573d6000803e3d6000fd5b505050506040513d608081101561298357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050809750819850829950839a5050505050600085141580156129fe57503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16145b1515612a0957600080fd5b600092505b8780549050831015612d425742612a6c8985815481101515612a2c57fe5b9060005260206000209060040201600301548a86815481101515612a4c57fe5b90600052602060002090600402016002015461496b90919063ffffffff16565b11158015612aab575042612aa88985815481101515612a8757fe5b9060005260206000209060040201600301548761496b90919063ffffffff16565b11155b15612d37578783815481101515612abe57fe5b90600052602060002090600402016001015491508873ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015612b4157600080fd5b505af1158015612b55573d6000803e3d6000fd5b505050506040513d6020811015612b6b57600080fd5b810190808051906020019092919050505090508783815481101515612b8c57fe5b9060005260206000209060040201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160009055600382016000905550508873ffffffffffffffffffffffffffffffffffffffff166342842e0e8233856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015612cb357600080fd5b505af1158015612cc7573d6000803e3d6000fd5b505050507f95681e512bc0fe659e195e06c283eada494316f3d801213e48e7101af92bf7708b83604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b826001019250612a0e565b5050505050505050505050565b600260149054906101000a900460ff1615612d6957600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612da357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332214874333485856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182151515158152602001945050505050600060405180830381600087803b158015612e7c57600080fd5b505af1158015612e90573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166372852fe5338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018461ffff1661ffff16815260200183815260200182151515158152602001945050505050600060405180830381600087803b158015612f7557600080fd5b505af1158015612f89573d6000803e3d6000fd5b50505050505050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612ff057600080fd5b600460008661ffff1661ffff16815260200190815260200160002091506000828054905011151561302057600080fd5b600090505b81805490508110156131bb5782828281548110151561304057fe5b9060005260206000209060040201600101541480156130c957508373ffffffffffffffffffffffffffffffffffffffff16828281548110151561307f57fe5b906000526020600020906004020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156131b05781818154811015156130dc57fe5b9060005260206000209060040201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160009055600382016000905550507f46cc5a4ac65c49e4620e528287cf1c349db9515832147e43a7532aa93a8dfdd485858542604051808561ffff1661ffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a15b806001019050613025565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561321d57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663421b2d8b826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156132da57600080fd5b505af11580156132ee573d6000803e3d6000fd5b505050507ff1e08403e8c6577dc32cd66518e15d1663f8bffdd495f968daa71684b278e90881868686864233604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001876000191660001916815260200180602001866000191660001916815260200185600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b838110156133ee5780820151818401526020810190506133d3565b50505050905090810190601f16801561341b5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a15050505050565b600260149054906101000a900460ff161561344f57600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561348957600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663421b2d8b336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561354657600080fd5b505af115801561355a573d6000803e3d6000fd5b505050507ff1e08403e8c6577dc32cd66518e15d1663f8bffdd495f968daa71684b278e90833878787874287604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001876000191660001916815260200180602001866000191660001916815260200185600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b8381101561365a57808201518184015260208101905061363f565b50505050905090810190601f1680156136875780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4212e9333843460006040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200184815260200183151515158152602001828103825285818151815260200191508051906020019060200280838360005b8381101561378d578082015181840152602081019050613772565b5050505090500195505050505050600060405180830381600087803b1580156137b557600080fd5b505af11580156137c9573d6000803e3d6000fd5b50505050505050505050565b60008060008060008060003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561381a57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631ba3afd3896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b1580156138b357600080fd5b505af11580156138c7573d6000803e3d6000fd5b505050506040513d60208110156138dd57600080fd5b8101908080519060200190929190505050955060008673ffffffffffffffffffffffffffffffffffffffff161415151561391657600080fd5b859450600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ac2c8bb5896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050608060405180830381600087803b1580156139b257600080fd5b505af11580156139c6573d6000803e3d6000fd5b505050506040513d60808110156139dc57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050809450819550829650839750505050508473ffffffffffffffffffffffffffffffffffffffff166380a1ba6a85846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015613abe57600080fd5b505af1158015613ad2573d6000803e3d6000fd5b505050506040513d6020811015613ae857600080fd5b81019080805190602001909291905050509650505050505050919050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613b6657600080fd5b600092505b8451831015613e5e578483815181101515613b8257fe5b906020019060200201519150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663aae40ddc836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808261ffff1661ffff168152602001915050602060405180830381600087803b158015613c2757600080fd5b505af1158015613c3b573d6000803e3d6000fd5b505050506040513d6020811015613c5157600080fd5b810190808051906020019092919050505090506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515613cbf57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632f54a61e83866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808361ffff1661ffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015613d8c57600080fd5b505af1158015613da0573d6000803e3d6000fd5b505050507f0936305ed8fb00934042531a7c9b5ac31f245e8891500f7ea7192f3912e2530f82853342604051808561ffff1661ffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390a1826001019250613b6b565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613ec057600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c26181e083836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018215151515815260200192505050600060405180830381600087803b158015613f8957600080fd5b505af1158015613f9d573d6000803e3d6000fd5b505050507fc661a5cc93e5e19e1839d5e38cc38bd2d6397f2e1396b1e167894642e8b44ce98282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a15050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561407157600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4c30ceb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156140f757600080fd5b505af115801561410b573d6000803e3d6000fd5b505050506040513d602081101561412157600080fd5b8101908080519060200190929190505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561419257600080fd5b600066038d7ea4c68000348115156141a657fe5b061415156141b357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663330ae7b382346040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561427857600080fd5b505af115801561428c573d6000803e3d6000fd5b5050505050565b600260149054906101000a900460ff16156142ad57600080fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156142e757600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332214874333485856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182151515158152602001945050505050600060405180830381600087803b1580156143c057600080fd5b505af11580156143d4573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c27bc7b2338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200184815260200183151515158152602001828103825285818151815260200191508051906020019060200280838360005b838110156144ca5780820151818401526020810190506144af565b5050505090500195505050505050600060405180830381600087803b1580156144f257600080fd5b505af1158015614506573d6000803e3d6000fd5b50505050505050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561456d57600080fd5b3073ffffffffffffffffffffffffffffffffffffffff16319150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4c30ceb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561460d57600080fd5b505af1158015614621573d6000803e3d6000fd5b505050506040513d602081101561463757600080fd5b8101908080519060200190929190505050905080821015614656578190505b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638580eb2f60006040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156146e857600080fd5b505af11580156146fc573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015614767573d6000803e3d6000fd5b505050565b60003273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156147a857600080fd5b6000821115156147b757600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166311bb20da33846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561487c57600080fd5b505af1158015614890573d6000803e3d6000fd5b505050506040513d60208110156148a657600080fd5b810190808051906020019092919050505090503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156148ff573d6000803e3d6000fd5b505050565b600082821115151561491257fe5b818303905092915050565b600080831415614930576000905061494f565b818302905081838281151561494157fe5b0414151561494b57fe5b8090505b92915050565b6000818381151561496257fe5b04905092915050565b6000818301905082811015151561497e57fe5b809050929150505600a165627a7a72305820ee7f70821b09947c36beeab5b3a2676c1d335f625776157a3245d04b16c860220029

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000168848b7ec6c61bd452ee6e74ae85b07cc3b8d1700000000000000000000000053d34d53a692e6352565909acda5af9145f11bf6

-----Decoded View---------------
Arg [0] : _bwService (address): 0x168848B7eC6C61BD452Ee6e74ae85b07CC3b8D17
Arg [1] : _bwData (address): 0x53d34d53a692E6352565909ACdA5AF9145F11Bf6

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000168848b7ec6c61bd452ee6e74ae85b07cc3b8d17
Arg [1] : 00000000000000000000000053d34d53a692e6352565909acda5af9145f11bf6


Swarm Source

bzzr://ee7f70821b09947c36beeab5b3a2676c1d335f625776157a3245d04b16c86022

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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.