ETH Price: $2,971.21 (-1.49%)
 

Overview

ETH Balance

1.189568691702556023 ETH

Eth Value

$3,534.45 (@ $2,971.21/ETH)

Token Holdings

More Info

Private Name Tags

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve109977972020-10-05 20:06:541740 days ago1601928414IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.0006954748
Buy Basic Unit64548232018-10-05 0:12:062472 days ago1538698326IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000138331
Buy Basic Unit61396912018-08-13 11:13:032524 days ago1534158783IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000290492.1
Buy Basic Unit54557492018-04-17 8:05:382643 days ago1523952338IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000152161.1
Withdraw Ether54494852018-04-16 6:40:262644 days ago1523860826IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000028421
Withdraw Ether54352002018-04-13 21:00:582646 days ago1523653258IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000070382
Withdraw Ether53947092018-04-07 2:48:532653 days ago1523069333IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000035511
Claim Research D...53945932018-04-07 2:23:442653 days ago1523067824IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000171971
Withdraw Ether53938312018-04-06 23:21:002653 days ago1523056860IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000035571
Buy Upgrade53929372018-04-06 19:48:562653 days ago1523044136IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000089941
Buy Raffle Ticke...53929302018-04-06 19:47:372653 days ago1523044057IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000022571
Buy Raffle Ticke...53929302018-04-06 19:47:372653 days ago1523044057IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000021991
Buy Upgrade53929102018-04-06 19:43:492653 days ago1523043829IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000107191
Buy Upgrade53870772018-04-05 20:43:542654 days ago1522961034IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000107891
Buy Upgrade53870772018-04-05 20:43:542654 days ago1522961034IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000105071
Buy Upgrade53870772018-04-05 20:43:542654 days ago1522961034IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000107891
Buy Upgrade53870772018-04-05 20:43:542654 days ago1522961034IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000105071
Buy Upgrade53870772018-04-05 20:43:542654 days ago1522961034IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000107891
Buy Upgrade53870772018-04-05 20:43:542654 days ago1522961034IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000110031
Buy Upgrade53870762018-04-05 20:43:172654 days ago1522960997IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000105071
Buy Upgrade53870762018-04-05 20:43:172654 days ago1522960997IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000110031
Buy Upgrade53870722018-04-05 20:42:552654 days ago1522960975IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000110011
Buy Upgrade53867602018-04-05 19:28:562654 days ago1522956536IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000032150.3
Withdraw Ether53797712018-04-04 15:13:012655 days ago1522854781IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.000028421
Buy Upgrade53763672018-04-04 1:49:212656 days ago1522806561IN
0xDDA9bcD9...9Dff5baF1
0 ETH0.0000180.2
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer54352002018-04-13 21:00:582646 days ago1523653258
0xDDA9bcD9...9Dff5baF1
6 wei
Transfer53947092018-04-07 2:48:532653 days ago1523069333
0xDDA9bcD9...9Dff5baF1
0.00023085 ETH
Transfer53938312018-04-06 23:21:002653 days ago1523056860
0xDDA9bcD9...9Dff5baF1
0.01458702 ETH
Transfer53754322018-04-03 22:07:092656 days ago1522793229
0xDDA9bcD9...9Dff5baF1
0.15885178 ETH
Transfer53751342018-04-03 21:01:092656 days ago1522789269
0xDDA9bcD9...9Dff5baF1
992 wei
Transfer53734622018-04-03 14:16:222656 days ago1522764982
0xDDA9bcD9...9Dff5baF1
0.27174285 ETH
Transfer53702242018-04-03 1:14:362657 days ago1522718076
0xDDA9bcD9...9Dff5baF1
0.00749999 ETH
Transfer53701502018-04-03 0:55:262657 days ago1522716926
0xDDA9bcD9...9Dff5baF1
0 ETH
Transfer53695332018-04-02 22:32:222657 days ago1522708342
0xDDA9bcD9...9Dff5baF1
0.00015906 ETH
Transfer53694002018-04-02 21:59:482657 days ago1522706388
0xDDA9bcD9...9Dff5baF1
0.0026548 ETH
Transfer53687722018-04-02 19:36:512657 days ago1522697811
0xDDA9bcD9...9Dff5baF1
0.0006637 ETH
Transfer53672342018-04-02 13:24:442657 days ago1522675484
0xDDA9bcD9...9Dff5baF1
0.01410423 ETH
Transfer53672272018-04-02 13:22:592657 days ago1522675379
0xDDA9bcD9...9Dff5baF1
0 ETH
Transfer53672202018-04-02 13:20:542657 days ago1522675254
0xDDA9bcD9...9Dff5baF1
0.00024411 ETH
Transfer53670452018-04-02 12:39:082657 days ago1522672748
0xDDA9bcD9...9Dff5baF1
0.00378866 ETH
Transfer53664912018-04-02 10:26:522657 days ago1522664812
0xDDA9bcD9...9Dff5baF1
0.00450423 ETH
Transfer53661692018-04-02 9:11:342658 days ago1522660294
0xDDA9bcD9...9Dff5baF1
0.0042343 ETH
Transfer53661472018-04-02 9:04:482658 days ago1522659888
0xDDA9bcD9...9Dff5baF1
0.11238918 ETH
Transfer53661392018-04-02 9:03:012658 days ago1522659781
0xDDA9bcD9...9Dff5baF1
0.07499999 ETH
Transfer53660092018-04-02 8:28:102658 days ago1522657690
0xDDA9bcD9...9Dff5baF1
0.00682372 ETH
Transfer53657522018-04-02 7:27:432658 days ago1522654063
0xDDA9bcD9...9Dff5baF1
0.15 ETH
Transfer53655142018-04-02 6:30:342658 days ago1522650634
0xDDA9bcD9...9Dff5baF1
0.00945054 ETH
Transfer53654902018-04-02 6:25:302658 days ago1522650330
0xDDA9bcD9...9Dff5baF1
0.1425 ETH
Transfer53654122018-04-02 6:09:282658 days ago1522649368
0xDDA9bcD9...9Dff5baF1
4.6575 ETH
Transfer53653632018-04-02 5:58:532658 days ago1522648733
0xDDA9bcD9...9Dff5baF1
0.39353862 ETH
View All Internal Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Goo

Compiler Version
v0.4.21+commit.dfe3193c

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2018-03-31
*/

pragma solidity ^0.4.0;

interface ERC20 {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

// GOO - Crypto Idle Game
// https://ethergoo.io

contract Goo is ERC20 {
    
    string public constant name  = "IdleEth";
    string public constant symbol = "Goo";
    uint8 public constant decimals = 0;
    uint256 private roughSupply;
    uint256 public totalGooProduction;
    address public owner; // Minor management of game
    bool public gameStarted;
    
    uint256 public totalEtherGooResearchPool; // Eth dividends to be split between players' goo production
    uint256[] public totalGooProductionSnapshots; // The total goo production for each prior day past
    uint256[] public allocatedGooResearchSnapshots; // The research eth allocated to each prior day past
    uint256 public nextSnapshotTime;
    
    uint256 private MAX_PRODUCTION_UNITS = 999; // Per type (makes balancing slightly easier)
    uint256 private constant RAFFLE_TICKET_BASE_GOO_PRICE = 1000;
    
    // Balances for each player
    mapping(address => uint256) private ethBalance;
    mapping(address => uint256) private gooBalance;
    mapping(address => mapping(uint256 => uint256)) private gooProductionSnapshots; // Store player's goo production for given day (snapshot)
    mapping(address => mapping(uint256 => bool)) private gooProductionZeroedSnapshots; // This isn't great but we need know difference between 0 production and an unused/inactive day.
    
    mapping(address => uint256) private lastGooSaveTime; // Seconds (last time player claimed their produced goo)
    mapping(address => uint256) public lastGooProductionUpdate; // Days (last snapshot player updated their production)
    mapping(address => uint256) private lastGooResearchFundClaim; // Days (snapshot number)
    mapping(address => uint256) private battleCooldown; // If user attacks they cannot attack again for short time
    
    // Stuff owned by each player
    mapping(address => mapping(uint256 => uint256)) private unitsOwned;
    mapping(address => mapping(uint256 => bool)) private upgradesOwned;
    mapping(uint256 => address) private rareItemOwner;
    mapping(uint256 => uint256) private rareItemPrice;
    
    // Rares & Upgrades (Increase unit's production / attack etc.)
    mapping(address => mapping(uint256 => uint256)) private unitGooProductionIncreases; // Adds to the goo per second
    mapping(address => mapping(uint256 => uint256)) private unitGooProductionMultiplier; // Multiplies the goo per second
    mapping(address => mapping(uint256 => uint256)) private unitAttackIncreases;
    mapping(address => mapping(uint256 => uint256)) private unitAttackMultiplier;
    mapping(address => mapping(uint256 => uint256)) private unitDefenseIncreases;
    mapping(address => mapping(uint256 => uint256)) private unitDefenseMultiplier;
    mapping(address => mapping(uint256 => uint256)) private unitGooStealingIncreases;
    mapping(address => mapping(uint256 => uint256)) private unitGooStealingMultiplier;
    
    // Mapping of approved ERC20 transfers (by player)
    mapping(address => mapping(address => uint256)) private allowed;
    mapping(address => bool) private protectedAddresses; // For npc exchanges (requires 0 goo production)
    
    // Raffle structures
    struct TicketPurchases {
        TicketPurchase[] ticketsBought;
        uint256 numPurchases; // Allows us to reset without clearing TicketPurchase[] (avoids potential for gas limit)
        uint256 raffleRareId;
    }
    
    // Allows us to query winner without looping (avoiding potential for gas limit)
    struct TicketPurchase {
        uint256 startId;
        uint256 endId;
    }
    
    // Raffle tickets
    mapping(address => TicketPurchases) private ticketsBoughtByPlayer;
    mapping(uint256 => address[]) private rafflePlayers; // Keeping a seperate list for each raffle has it's benefits.

    // Current raffle info
    uint256 private raffleEndTime;
    uint256 private raffleRareId;
    uint256 private raffleTicketsBought;
    address private raffleWinner; // Address of winner
    bool private raffleWinningTicketSelected;
    uint256 private raffleTicketThatWon;
    
    // Minor game events
    event UnitBought(address player, uint256 unitId, uint256 amount);
    event UnitSold(address player, uint256 unitId, uint256 amount);
    event PlayerAttacked(address attacker, address target, bool success, uint256 gooStolen);
    
    GooGameConfig schema;
    
    // Constructor
    function Goo() public payable {
        owner = msg.sender;
        schema = GooGameConfig(0x21912e81d7eff8bff895302b45da76f7f070e3b9);
    }
    
    function() payable { }
    
    function beginGame(uint256 firstDivsTime) external payable {
        require(msg.sender == owner);
        require(!gameStarted);
        
        gameStarted = true; // GO-OOOO!
        nextSnapshotTime = firstDivsTime;
        totalEtherGooResearchPool = msg.value; // Seed pot
    }
    
    function totalSupply() public constant returns(uint256) {
        return roughSupply; // Stored goo (rough supply as it ignores earned/unclaimed goo)
    }
    
    function balanceOf(address player) public constant returns(uint256) {
        return gooBalance[player] + balanceOfUnclaimedGoo(player);
    }
    
    function balanceOfUnclaimedGoo(address player) internal constant returns (uint256) {
        if (lastGooSaveTime[player] > 0 && lastGooSaveTime[player] < block.timestamp) {
            return (getGooProduction(player) * (block.timestamp - lastGooSaveTime[player]));
        }
        return 0;
    }
    
    function etherBalanceOf(address player) public constant returns(uint256) {
        return ethBalance[player];
    }
    
    function transfer(address recipient, uint256 amount) public returns (bool) {
        updatePlayersGoo(msg.sender);
        require(amount <= gooBalance[msg.sender]);
        
        gooBalance[msg.sender] -= amount;
        gooBalance[recipient] += amount;
        
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }
    
    function transferFrom(address player, address recipient, uint256 amount) public returns (bool) {
        updatePlayersGoo(player);
        require(amount <= allowed[player][msg.sender] && amount <= gooBalance[msg.sender]);
        
        gooBalance[player] -= amount;
        gooBalance[recipient] += amount;
        allowed[player][msg.sender] -= amount;
        
        emit Transfer(player, recipient, amount);
        return true;
    }
    
    function approve(address approvee, uint256 amount) public returns (bool){
        allowed[msg.sender][approvee] = amount;
        emit Approval(msg.sender, approvee, amount);
        return true;
    }
    
    function allowance(address player, address approvee) public constant returns(uint256){
        return allowed[player][approvee];
    }
    
    function getGooProduction(address player) public constant returns (uint256){
        return gooProductionSnapshots[player][lastGooProductionUpdate[player]];
    }
    
    function updatePlayersGoo(address player) internal {
        uint256 gooGain = balanceOfUnclaimedGoo(player);
        lastGooSaveTime[player] = block.timestamp;
        roughSupply += gooGain;
        gooBalance[player] += gooGain;
    }
    
    function updatePlayersGooFromPurchase(address player, uint256 purchaseCost) internal {
        uint256 unclaimedGoo = balanceOfUnclaimedGoo(player);
        
        if (purchaseCost > unclaimedGoo) {
            uint256 gooDecrease = purchaseCost - unclaimedGoo;
            roughSupply -= gooDecrease;
            gooBalance[player] -= gooDecrease;
        } else {
            uint256 gooGain = unclaimedGoo - purchaseCost;
            roughSupply += gooGain;
            gooBalance[player] += gooGain;
        }
        
        lastGooSaveTime[player] = block.timestamp;
    }
    
    function increasePlayersGooProduction(uint256 increase) internal {
        gooProductionSnapshots[msg.sender][allocatedGooResearchSnapshots.length] = getGooProduction(msg.sender) + increase;
        lastGooProductionUpdate[msg.sender] = allocatedGooResearchSnapshots.length;
        totalGooProduction += increase;
    }
    
    function reducePlayersGooProduction(address player, uint256 decrease) internal {
        uint256 previousProduction = getGooProduction(player);
        uint256 newProduction = SafeMath.sub(previousProduction, decrease);
        
        if (newProduction == 0) { // Special case which tangles with "inactive day" snapshots (claiming divs)
            gooProductionZeroedSnapshots[player][allocatedGooResearchSnapshots.length] = true;
            delete gooProductionSnapshots[player][allocatedGooResearchSnapshots.length]; // 0
        } else {
            gooProductionSnapshots[player][allocatedGooResearchSnapshots.length] = newProduction;
        }
        
        lastGooProductionUpdate[player] = allocatedGooResearchSnapshots.length;
        totalGooProduction -= decrease;
    }
    
    function buyBasicUnit(uint256 unitId, uint256 amount) external {
        require(gameStarted);
        require(schema.validUnitId(unitId));
        require(unitsOwned[msg.sender][unitId] + amount <= MAX_PRODUCTION_UNITS);
        
        uint256 unitCost = schema.getGooCostForUnit(unitId, unitsOwned[msg.sender][unitId], amount);
        require(balanceOf(msg.sender) >= unitCost);
        require(schema.unitEthCost(unitId) == 0); // Free unit
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, unitCost);
        
        if (schema.unitGooProduction(unitId) > 0) {
            increasePlayersGooProduction(getUnitsProduction(msg.sender, unitId, amount));
        }
        
        unitsOwned[msg.sender][unitId] += amount;
        emit UnitBought(msg.sender, unitId, amount);
    }
    
    function buyEthUnit(uint256 unitId, uint256 amount) external payable {
        require(gameStarted);
        require(schema.validUnitId(unitId));
        require(unitsOwned[msg.sender][unitId] + amount <= MAX_PRODUCTION_UNITS);
        
        uint256 unitCost = schema.getGooCostForUnit(unitId, unitsOwned[msg.sender][unitId], amount);
        uint256 ethCost = SafeMath.mul(schema.unitEthCost(unitId), amount);
        
        require(balanceOf(msg.sender) >= unitCost);
        require(ethBalance[msg.sender] + msg.value >= ethCost);
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, unitCost);

        if (ethCost > msg.value) {
            ethBalance[msg.sender] -= (ethCost - msg.value);
        }
        
        uint256 devFund = ethCost / 50; // 2% fee on purchases (marketing, gameplay & maintenance)
        uint256 dividends = (ethCost - devFund) / 4; // 25% goes to pool (75% retained for sale value)
        totalEtherGooResearchPool += dividends;
        ethBalance[owner] += devFund;
        
        if (schema.unitGooProduction(unitId) > 0) {
            increasePlayersGooProduction(getUnitsProduction(msg.sender, unitId, amount));
        }
        
        unitsOwned[msg.sender][unitId] += amount;
        emit UnitBought(msg.sender, unitId, amount);
    }
    
    function sellUnit(uint256 unitId, uint256 amount) external {
        require(unitsOwned[msg.sender][unitId] >= amount);
        unitsOwned[msg.sender][unitId] -= amount;
        
        uint256 unitSalePrice = (schema.getGooCostForUnit(unitId, unitsOwned[msg.sender][unitId], amount) * 3) / 4; // 75%
        uint256 gooChange = balanceOfUnclaimedGoo(msg.sender) + unitSalePrice; // Claim unsaved goo whilst here
        lastGooSaveTime[msg.sender] = block.timestamp;
        roughSupply += gooChange;
        gooBalance[msg.sender] += gooChange;
        
        if (schema.unitGooProduction(unitId) > 0) {
            reducePlayersGooProduction(msg.sender, getUnitsProduction(msg.sender, unitId, amount));
        }
        
        if (schema.unitEthCost(unitId) > 0) { // Premium units sell for 75% of buy cost
            ethBalance[msg.sender] += ((schema.unitEthCost(unitId) * amount) * 3) / 4;
        }
        emit UnitSold(msg.sender, unitId, amount);
    }
    
    function buyUpgrade(uint256 upgradeId) external payable {
        require(gameStarted);
        require(schema.validUpgradeId(upgradeId)); // Valid upgrade
        require(!upgradesOwned[msg.sender][upgradeId]); // Haven't already purchased
        
        uint256 gooCost;
        uint256 ethCost;
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
        (gooCost, ethCost, upgradeClass, unitId, upgradeValue) = schema.getUpgradeInfo(upgradeId);
        
        require(balanceOf(msg.sender) >= gooCost);
        
        if (ethCost > 0) {
            require(ethBalance[msg.sender] + msg.value >= ethCost);
             if (ethCost > msg.value) { // They can use their balance instead
                ethBalance[msg.sender] -= (ethCost - msg.value);
            }
        
            uint256 devFund = ethCost / 50; // 2% fee on purchases (marketing, gameplay & maintenance)
            totalEtherGooResearchPool += (ethCost - devFund); // Rest goes to div pool (Can't sell upgrades)
            ethBalance[owner] += devFund;
        }
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, gooCost);

        upgradeUnitMultipliers(msg.sender, upgradeClass, unitId, upgradeValue);
        upgradesOwned[msg.sender][upgradeId] = true;
    }
    
    function upgradeUnitMultipliers(address player, uint256 upgradeClass, uint256 unitId, uint256 upgradeValue) internal {
        uint256 productionGain;
        if (upgradeClass == 0) {
            unitGooProductionIncreases[player][unitId] += upgradeValue;
            productionGain = (unitsOwned[player][unitId] * upgradeValue * (10 + unitGooProductionMultiplier[player][unitId])) / 10;
            increasePlayersGooProduction(productionGain);
        } else if (upgradeClass == 1) {
            unitGooProductionMultiplier[player][unitId] += upgradeValue;
            productionGain = (unitsOwned[player][unitId] * upgradeValue * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId])) / 10;
            increasePlayersGooProduction(productionGain);
        } else if (upgradeClass == 2) {
            unitAttackIncreases[player][unitId] += upgradeValue;
        } else if (upgradeClass == 3) {
            unitAttackMultiplier[player][unitId] += upgradeValue;
        } else if (upgradeClass == 4) {
            unitDefenseIncreases[player][unitId] += upgradeValue;
        } else if (upgradeClass == 5) {
            unitDefenseMultiplier[player][unitId] += upgradeValue;
        } else if (upgradeClass == 6) {
            unitGooStealingIncreases[player][unitId] += upgradeValue;
        } else if (upgradeClass == 7) {
            unitGooStealingMultiplier[player][unitId] += upgradeValue;
        }
    }
    
    function removeUnitMultipliers(address player, uint256 upgradeClass, uint256 unitId, uint256 upgradeValue) internal {
        uint256 productionLoss;
        if (upgradeClass == 0) {
            unitGooProductionIncreases[player][unitId] -= upgradeValue;
            productionLoss = (unitsOwned[player][unitId] * upgradeValue * (10 + unitGooProductionMultiplier[player][unitId])) / 10;
            reducePlayersGooProduction(player, productionLoss);
        } else if (upgradeClass == 1) {
            unitGooProductionMultiplier[player][unitId] -= upgradeValue;
            productionLoss = (unitsOwned[player][unitId] * upgradeValue * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId])) / 10;
            reducePlayersGooProduction(player, productionLoss);
        } else if (upgradeClass == 2) {
            unitAttackIncreases[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 3) {
            unitAttackMultiplier[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 4) {
            unitDefenseIncreases[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 5) {
            unitDefenseMultiplier[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 6) {
            unitGooStealingIncreases[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 7) {
            unitGooStealingMultiplier[player][unitId] -= upgradeValue;
        }
    }
    
    function buyRareItem(uint256 rareId) external payable {
        require(schema.validRareId(rareId));
        
        address previousOwner = rareItemOwner[rareId];
        require(previousOwner != 0);

        uint256 ethCost = rareItemPrice[rareId];
        require(ethBalance[msg.sender] + msg.value >= ethCost);
        
        // We have to claim buyer's goo before updating their production values
        updatePlayersGoo(msg.sender);
        
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
        (upgradeClass, unitId, upgradeValue) = schema.getRareInfo(rareId);
        upgradeUnitMultipliers(msg.sender, upgradeClass, unitId, upgradeValue);
        
        // We have to claim seller's goo before reducing their production values
        updatePlayersGoo(previousOwner);
        removeUnitMultipliers(previousOwner, upgradeClass, unitId, upgradeValue);
        
        // Splitbid/Overbid
        if (ethCost > msg.value) {
            // Earlier require() said they can still afford it (so use their ingame balance)
            ethBalance[msg.sender] -= (ethCost - msg.value);
        } else if (msg.value > ethCost) {
            // Store overbid in their balance
            ethBalance[msg.sender] += msg.value - ethCost;
        }
        
        // Distribute ethCost
        uint256 devFund = ethCost / 50; // 2% fee on purchases (marketing, gameplay & maintenance)
        uint256 dividends = ethCost / 20; // 5% goes to pool (~93% goes to player)
        totalEtherGooResearchPool += dividends;
        ethBalance[owner] += devFund;
        
        // Transfer / update rare item
        rareItemOwner[rareId] = msg.sender;
        rareItemPrice[rareId] = (ethCost * 5) / 4; // 25% price flip increase
        ethBalance[previousOwner] += ethCost - (dividends + devFund);
    }
    
    function withdrawEther(uint256 amount) external {
        require(amount <= ethBalance[msg.sender]);
        ethBalance[msg.sender] -= amount;
        msg.sender.transfer(amount);
    }
    
    function claimResearchDividends(address referer, uint256 startSnapshot, uint256 endSnapShot) external {
        require(startSnapshot <= endSnapShot);
        require(startSnapshot >= lastGooResearchFundClaim[msg.sender]);
        require(endSnapShot < allocatedGooResearchSnapshots.length);
        
        uint256 researchShare;
        uint256 previousProduction = gooProductionSnapshots[msg.sender][lastGooResearchFundClaim[msg.sender] - 1]; // Underflow won't be a problem as gooProductionSnapshots[][0xffffffffff] = 0;
        for (uint256 i = startSnapshot; i <= endSnapShot; i++) {
            
            // Slightly complex things by accounting for days/snapshots when user made no tx's
            uint256 productionDuringSnapshot = gooProductionSnapshots[msg.sender][i];
            bool soldAllProduction = gooProductionZeroedSnapshots[msg.sender][i];
            if (productionDuringSnapshot == 0 && !soldAllProduction) {
                productionDuringSnapshot = previousProduction;
            } else {
               previousProduction = productionDuringSnapshot;
            }
            
            researchShare += (allocatedGooResearchSnapshots[i] * productionDuringSnapshot) / totalGooProductionSnapshots[i];
        }
        
        
        if (gooProductionSnapshots[msg.sender][endSnapShot] == 0 && !gooProductionZeroedSnapshots[msg.sender][i] && previousProduction > 0) {
            gooProductionSnapshots[msg.sender][endSnapShot] = previousProduction; // Checkpoint for next claim
        }
        
        lastGooResearchFundClaim[msg.sender] = endSnapShot + 1;
        
        uint256 referalDivs;
        if (referer != address(0) && referer != msg.sender) {
            referalDivs = researchShare / 100; // 1%
            ethBalance[referer] += referalDivs;
        }
        
        ethBalance[msg.sender] += researchShare - referalDivs;
    }
    
    // Allocate divs for the day (cron job)
    function snapshotDailyGooResearchFunding() external {
        require(msg.sender == owner);
        //require(block.timestamp >= (nextSnapshotTime - 30 minutes)); // Small bit of leeway for cron / network
        
        uint256 todaysEtherResearchFund = (totalEtherGooResearchPool / 10); // 10% of pool daily
        totalEtherGooResearchPool -= todaysEtherResearchFund;
        
        totalGooProductionSnapshots.push(totalGooProduction);
        allocatedGooResearchSnapshots.push(todaysEtherResearchFund);
        nextSnapshotTime = block.timestamp + 24 hours;
    }
    
    
    
    // Raffle for rare items
    function buyRaffleTicket(uint256 amount) external {
        require(raffleEndTime >= block.timestamp);
        require(amount > 0);
        
        uint256 ticketsCost = SafeMath.mul(RAFFLE_TICKET_BASE_GOO_PRICE, amount);
        require(balanceOf(msg.sender) >= ticketsCost);
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, ticketsCost);
        
        // Handle new tickets
        TicketPurchases storage purchases = ticketsBoughtByPlayer[msg.sender];
        
        // If we need to reset tickets from a previous raffle
        if (purchases.raffleRareId != raffleRareId) {
            purchases.numPurchases = 0;
            purchases.raffleRareId = raffleRareId;
            rafflePlayers[raffleRareId].push(msg.sender); // Add user to raffle
        }
        
        // Store new ticket purchase 
        if (purchases.numPurchases == purchases.ticketsBought.length) {
            purchases.ticketsBought.length += 1;
        }
        purchases.ticketsBought[purchases.numPurchases++] = TicketPurchase(raffleTicketsBought, raffleTicketsBought + (amount - 1)); // (eg: buy 10, get id's 0-9)
        
        // Finally update ticket total
        raffleTicketsBought += amount;
    }
    
    function startRareRaffle(uint256 endTime, uint256 rareId) external {
        require(msg.sender == owner);
        require(schema.validRareId(rareId));
        require(rareItemOwner[rareId] == 0);
        
        // Reset previous raffle info
        raffleWinningTicketSelected = false;
        raffleTicketThatWon = 0;
        raffleWinner = 0;
        raffleTicketsBought = 0;
        
        // Set current raffle info
        raffleEndTime = endTime;
        raffleRareId = rareId;
    }
    
    function awardRafflePrize(address checkWinner, uint256 checkIndex) external {
        require(raffleEndTime < block.timestamp);
        require(raffleWinner == 0);
        require(rareItemOwner[raffleRareId] == 0);
        
        if (!raffleWinningTicketSelected) {
            drawRandomWinner(); // Ideally do it in one call (gas limit cautious)
        }
        
        // Reduce gas by (optionally) offering an address to _check_ for winner
        if (checkWinner != 0) {
            TicketPurchases storage tickets = ticketsBoughtByPlayer[checkWinner];
            if (tickets.numPurchases > 0 && checkIndex < tickets.numPurchases && tickets.raffleRareId == raffleRareId) {
                TicketPurchase storage checkTicket = tickets.ticketsBought[checkIndex];
                if (raffleTicketThatWon >= checkTicket.startId && raffleTicketThatWon <= checkTicket.endId) {
                    assignRafflePrize(checkWinner); // WINNER!
                    return;
                }
            }
        }
        
        // Otherwise just naively try to find the winner (will work until mass amounts of players)
        for (uint256 i = 0; i < rafflePlayers[raffleRareId].length; i++) {
            address player = rafflePlayers[raffleRareId][i];
            TicketPurchases storage playersTickets = ticketsBoughtByPlayer[player];
            
            uint256 endIndex = playersTickets.numPurchases - 1;
            // Minor optimization to avoid checking every single player
            if (raffleTicketThatWon >= playersTickets.ticketsBought[0].startId && raffleTicketThatWon <= playersTickets.ticketsBought[endIndex].endId) {
                for (uint256 j = 0; j < playersTickets.numPurchases; j++) {
                    TicketPurchase storage playerTicket = playersTickets.ticketsBought[j];
                    if (raffleTicketThatWon >= playerTicket.startId && raffleTicketThatWon <= playerTicket.endId) {
                        assignRafflePrize(player); // WINNER!
                        return;
                    }
                }
            }
        }
    }
    
    function assignRafflePrize(address winner) internal {
        raffleWinner = winner;
        rareItemOwner[raffleRareId] = winner;
        rareItemPrice[raffleRareId] = (schema.rareStartPrice(raffleRareId) * 21) / 20; // Buy price slightly higher (Div pool cut)
        
        updatePlayersGoo(winner);
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
        (upgradeClass, unitId, upgradeValue) = schema.getRareInfo(raffleRareId);
        upgradeUnitMultipliers(winner, upgradeClass, unitId, upgradeValue);
    }
    
    // Random enough for small contests (Owner only to prevent trial & error execution)
    function drawRandomWinner() public {
        require(msg.sender == owner);
        require(raffleEndTime < block.timestamp);
        require(!raffleWinningTicketSelected);
        
        uint256 seed = raffleTicketsBought + block.timestamp;
        raffleTicketThatWon = addmod(uint256(block.blockhash(block.number-1)), seed, raffleTicketsBought);
        raffleWinningTicketSelected = true;
    }
    
    
    
    function protectAddress(address exchange, bool isProtected) external {
        require(msg.sender == owner);
        require(getGooProduction(exchange) == 0); // Can't protect actual players
        protectedAddresses[exchange] = isProtected;
    }
    
    function attackPlayer(address target) external {
        require(battleCooldown[msg.sender] < block.timestamp);
        require(target != msg.sender);
        require(!protectedAddresses[target]); //target not whitelisted (i.e. exchange wallets)
        
        uint256 attackingPower;
        uint256 defendingPower;
        uint256 stealingPower;
        (attackingPower, defendingPower, stealingPower) = getPlayersBattlePower(msg.sender, target);
        
        if (battleCooldown[target] > block.timestamp) { // When on battle cooldown you're vulnerable (starting value is 50% normal power)
            defendingPower = schema.getWeakenedDefensePower(defendingPower);
        }
        
        if (attackingPower > defendingPower) {
            battleCooldown[msg.sender] = block.timestamp + 30 minutes;
            if (balanceOf(target) > stealingPower) {
                // Save all their unclaimed goo, then steal attacker's max capacity (at same time)
                uint256 unclaimedGoo = balanceOfUnclaimedGoo(target);
                if (stealingPower > unclaimedGoo) {
                    uint256 gooDecrease = stealingPower - unclaimedGoo;
                    gooBalance[target] -= gooDecrease;
                } else {
                    uint256 gooGain = unclaimedGoo - stealingPower;
                    gooBalance[target] += gooGain;
                }
                gooBalance[msg.sender] += stealingPower;
                emit PlayerAttacked(msg.sender, target, true, stealingPower);
            } else {
                emit PlayerAttacked(msg.sender, target, true, balanceOf(target));
                gooBalance[msg.sender] += balanceOf(target);
                gooBalance[target] = 0;
            }
            
            lastGooSaveTime[target] = block.timestamp; 
            // We don't need to claim/save msg.sender's goo (as production delta is unchanged)
        } else {
            battleCooldown[msg.sender] = block.timestamp + 10 minutes;
            emit PlayerAttacked(msg.sender, target, false, 0);
        }
    }
    
    function getPlayersBattlePower(address attacker, address defender) internal constant returns (uint256, uint256, uint256) {
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.battleUnitIdRange();
        
        uint256 attackingPower;
        uint256 defendingPower;
        uint256 stealingPower;

        // Not ideal but will only be a small number of units (and saves gas when buying units)
        while (startId <= endId) {
            attackingPower += getUnitsAttack(attacker, startId, unitsOwned[attacker][startId]);
            stealingPower += getUnitsStealingCapacity(attacker, startId, unitsOwned[attacker][startId]);
            
            defendingPower += getUnitsDefense(defender, startId, unitsOwned[defender][startId]);
            startId++;
        }
        return (attackingPower, defendingPower, stealingPower);
    }
    
    function getPlayersBattleStats(address player) external constant returns (uint256, uint256, uint256) {
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.battleUnitIdRange();
        
        uint256 attackingPower;
        uint256 defendingPower;
        uint256 stealingPower;

        // Not ideal but will only be a small number of units (and saves gas when buying units)
        while (startId <= endId) {
            attackingPower += getUnitsAttack(player, startId, unitsOwned[player][startId]);
            stealingPower += getUnitsStealingCapacity(player, startId, unitsOwned[player][startId]);
            defendingPower += getUnitsDefense(player, startId, unitsOwned[player][startId]);
            startId++;
        }
        return (attackingPower, defendingPower, stealingPower);
    }
    
    function getUnitsProduction(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId]) * (10 + unitGooProductionMultiplier[player][unitId])) / 10;
    }
    
    function getUnitsAttack(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitAttack(unitId) + unitAttackIncreases[player][unitId]) * (10 + unitAttackMultiplier[player][unitId])) / 10;
    }
    
    function getUnitsDefense(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitDefense(unitId) + unitDefenseIncreases[player][unitId]) * (10 + unitDefenseMultiplier[player][unitId])) / 10;
    }
    
    function getUnitsStealingCapacity(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitStealingCapacity(unitId) + unitGooStealingIncreases[player][unitId]) * (10 + unitGooStealingMultiplier[player][unitId])) / 10;
    }
    
    
    // To display on website
    function getGameInfo() external constant returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256[], bool[]){
        uint256[] memory units = new uint256[](schema.currentNumberOfUnits());
        bool[] memory upgrades = new bool[](schema.currentNumberOfUpgrades());
        
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.productionUnitIdRange();
        
        uint256 i;
        while (startId <= endId) {
            units[i] = unitsOwned[msg.sender][startId];
            i++;
            startId++;
        }
        
        (startId, endId) = schema.battleUnitIdRange();
        while (startId <= endId) {
            units[i] = unitsOwned[msg.sender][startId];
            i++;
            startId++;
        }
        
        // Reset for upgrades
        i = 0;
        (startId, endId) = schema.upgradeIdRange();
        while (startId <= endId) {
            upgrades[i] = upgradesOwned[msg.sender][startId];
            i++;
            startId++;
        }
        
        return (block.timestamp, totalEtherGooResearchPool, totalGooProduction, nextSnapshotTime, balanceOf(msg.sender), ethBalance[msg.sender], getGooProduction(msg.sender), units, upgrades);
    }
    
    // To display on website
    function getRareItemInfo() external constant returns (address[], uint256[]) {
        address[] memory itemOwners = new address[](schema.currentNumberOfRares());
        uint256[] memory itemPrices = new uint256[](schema.currentNumberOfRares());
        
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.rareIdRange();
        
        uint256 i;
        while (startId <= endId) {
            itemOwners[i] = rareItemOwner[startId];
            itemPrices[i] = rareItemPrice[startId];
            
            i++;
            startId++;
        }
        
        return (itemOwners, itemPrices);
    }
    
    // To display on website
     function viewUnclaimedResearchDividends() external constant returns (uint256, uint256, uint256) {
        uint256 startSnapshot = lastGooResearchFundClaim[msg.sender];
        uint256 latestSnapshot = allocatedGooResearchSnapshots.length - 1; // No snapshots to begin with
        
        uint256 researchShare;
        uint256 previousProduction = gooProductionSnapshots[msg.sender][lastGooResearchFundClaim[msg.sender] - 1]; // Underflow won't be a problem as gooProductionSnapshots[][0xfffffffffffff] = 0;
        for (uint256 i = startSnapshot; i <= latestSnapshot; i++) {
            
            // Slightly complex things by accounting for days/snapshots when user made no tx's
            uint256 productionDuringSnapshot = gooProductionSnapshots[msg.sender][i];
            bool soldAllProduction = gooProductionZeroedSnapshots[msg.sender][i];
            if (productionDuringSnapshot == 0 && !soldAllProduction) {
                productionDuringSnapshot = previousProduction;
            } else {
               previousProduction = productionDuringSnapshot;
            }
            
            researchShare += (allocatedGooResearchSnapshots[i] * productionDuringSnapshot) / totalGooProductionSnapshots[i];
        }
        return (researchShare, startSnapshot, latestSnapshot);
    }
    
    
    // To allow clients to verify contestants
    function getRafflePlayers(uint256 raffleId) external constant returns (address[]) {
        return (rafflePlayers[raffleId]);
    }
    
    // To allow clients to verify contestants
    function getPlayersTickets(address player) external constant returns (uint256[], uint256[]) {
        TicketPurchases storage playersTickets = ticketsBoughtByPlayer[player];
        
        if (playersTickets.raffleRareId == raffleRareId) {
            uint256[] memory startIds = new uint256[](playersTickets.numPurchases);
            uint256[] memory endIds = new uint256[](playersTickets.numPurchases);
            
            for (uint256 i = 0; i < playersTickets.numPurchases; i++) {
                startIds[i] = playersTickets.ticketsBought[i].startId;
                endIds[i] = playersTickets.ticketsBought[i].endId;
            }
        }
        
        return (startIds, endIds);
    }
    
    // To display on website
    function getLatestRaffleInfo() external constant returns (uint256, uint256, uint256, address, uint256) {
        return (raffleEndTime, raffleRareId, raffleTicketsBought, raffleWinner, raffleTicketThatWon);
    }
    
    
    // New units may be added in future, but check it matches existing schema so no-one can abuse selling.
    function updateGooConfig(address newSchemaAddress) external {
        require(msg.sender == owner);
        
        GooGameConfig newSchema = GooGameConfig(newSchemaAddress);
        requireExistingUnitsSame(newSchema);
        requireExistingUpgradesSame(newSchema);
        
        // Finally update config
        schema = GooGameConfig(newSchema);
    }
    
    function requireExistingUnitsSame(GooGameConfig newSchema) internal constant {
        // Requires units eth costs match up or fail execution
        
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.productionUnitIdRange();
        while (startId <= endId) {
            require(schema.unitEthCost(startId) == newSchema.unitEthCost(startId));
            require(schema.unitGooProduction(startId) == newSchema.unitGooProduction(startId));
            startId++;
        }
        
        (startId, endId) = schema.battleUnitIdRange();
        while (startId <= endId) {
            require(schema.unitEthCost(startId) == newSchema.unitEthCost(startId));
            require(schema.unitAttack(startId) == newSchema.unitAttack(startId));
            require(schema.unitDefense(startId) == newSchema.unitDefense(startId));
            require(schema.unitStealingCapacity(startId) == newSchema.unitStealingCapacity(startId));
            startId++;
        }
    }
    
    function requireExistingUpgradesSame(GooGameConfig newSchema) internal constant {
        uint256 startId;
        uint256 endId;
        
        uint256 oldClass;
        uint256 oldUnitId;
        uint256 oldValue;
        
        uint256 newClass;
        uint256 newUnitId;
        uint256 newValue;
        
        // Requires ALL upgrade stats match up or fail execution
        (startId, endId) = schema.rareIdRange();
        while (startId <= endId) {
            uint256 oldGooCost;
            uint256 oldEthCost;
            (oldGooCost, oldEthCost, oldClass, oldUnitId, oldValue) = schema.getUpgradeInfo(startId);
            
            uint256 newGooCost;
            uint256 newEthCost;
            (newGooCost, newEthCost, newClass, newUnitId, newValue) = newSchema.getUpgradeInfo(startId);
            
            require(oldGooCost == newGooCost);
            require(oldEthCost == oldEthCost);
            require(oldClass == oldClass);
            require(oldUnitId == newUnitId);
            require(oldValue == newValue);
            startId++;
        }
        
        // Requires ALL rare stats match up or fail execution
        (startId, endId) = schema.rareIdRange();
        while (startId <= endId) {
            (oldClass, oldUnitId, oldValue) = schema.getRareInfo(startId);
            (newClass, newUnitId, newValue) = newSchema.getRareInfo(startId);
            
            require(oldClass == newClass);
            require(oldUnitId == newUnitId);
            require(oldValue == newValue);
            startId++;
        }
    }
}


contract GooGameConfig {
    
    mapping(uint256 => Unit) private unitInfo;
    mapping(uint256 => Upgrade) private upgradeInfo;
    mapping(uint256 => Rare) private rareInfo;
    
    uint256 public constant currentNumberOfUnits = 14;
    uint256 public constant currentNumberOfUpgrades = 42;
    uint256 public constant currentNumberOfRares = 2;
    
    struct Unit {
        uint256 unitId;
        uint256 baseGooCost;
        uint256 gooCostIncreaseHalf; // Halfed to make maths slightly less (cancels a 2 out)
        uint256 ethCost;
        uint256 baseGooProduction;
        
        uint256 attackValue;
        uint256 defenseValue;
        uint256 gooStealingCapacity;
    }
    
    struct Upgrade {
        uint256 upgradeId;
        uint256 gooCost;
        uint256 ethCost;
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
    }
    
     struct Rare {
        uint256 rareId;
        uint256 ethCost;
        uint256 rareClass;
        uint256 unitId;
        uint256 rareValue;
    }
    
    // Constructor
    function GooGameConfig() public {
        
        unitInfo[1] = Unit(1, 0, 10, 0, 1, 0, 0, 0);
        unitInfo[2] = Unit(2, 100, 50, 0, 2, 0, 0, 0);
        unitInfo[3] = Unit(3, 0, 0, 0.01 ether, 12, 0, 0, 0);
        unitInfo[4] = Unit(4, 500, 250, 0, 4, 0, 0, 0);
        unitInfo[5] = Unit(5, 2500, 1250, 0, 6, 0, 0, 0);
        unitInfo[6] = Unit(6, 10000, 5000, 0, 8, 0, 0, 0);
        unitInfo[7] = Unit(7, 0, 1000, 0.05 ether, 60, 0, 0, 0);
        unitInfo[8] = Unit(8, 25000, 12500, 0, 10, 0, 0, 0);
        
        unitInfo[40] = Unit(40, 100, 50, 0, 0, 10, 10, 20);
        unitInfo[41] = Unit(41, 250, 125, 0, 0, 1, 25, 1);
        unitInfo[42] = Unit(42, 0, 50, 0.01 ether, 0, 100, 10, 5);
        unitInfo[43] = Unit(43, 1000, 500, 0, 0, 25, 1, 50);
        unitInfo[44] = Unit(44, 2500, 1250, 0, 0, 20, 40, 100);
        unitInfo[45] = Unit(45, 0, 500, 0.02 ether, 0, 0, 0, 1000);
        
        upgradeInfo[1] = Upgrade(1, 500, 0, 0, 1, 1); // +1
        upgradeInfo[2] = Upgrade(2, 0, 0.1 ether, 1, 1, 10); // 10 = +100%
        upgradeInfo[3] = Upgrade(3, 10000, 0, 1, 1, 5); // 5 = +50%
        
        upgradeInfo[4] = Upgrade(4, 0, 0.1 ether, 0, 2, 2); // +1
        upgradeInfo[5] = Upgrade(5, 2000, 0, 1, 2, 5); // 10 = +50%
        upgradeInfo[6] = Upgrade(6, 0, 0.2 ether, 0, 2, 2); // +2
        
        upgradeInfo[7] = Upgrade(7, 2500, 0, 0, 3, 2); // +2
        upgradeInfo[8] = Upgrade(8, 0, 0.5 ether, 1, 3, 10); // 10 = +100%
        upgradeInfo[9] = Upgrade(9, 25000, 0, 1, 3, 5); // 5 = +50%
        
        upgradeInfo[10] = Upgrade(10, 0, 0.1 ether, 0, 4, 1); // +1
        upgradeInfo[11] = Upgrade(11, 5000, 0, 1, 4, 5); // 10 = +50%
        upgradeInfo[12] = Upgrade(12, 0, 0.2 ether, 0, 4, 2); // +2
        
        upgradeInfo[13] = Upgrade(13, 10000, 0, 0, 5, 2); // +2
        upgradeInfo[14] = Upgrade(14, 0, 0.5 ether, 1, 5, 10); // 10 = +100%
        upgradeInfo[15] = Upgrade(15, 25000, 0, 1, 5, 5); // 5 = +50%
        
        upgradeInfo[16] = Upgrade(16, 0, 0.1 ether, 0, 6, 1); // +1
        upgradeInfo[17] = Upgrade(17, 25000, 0, 1, 6, 5); // 10 = +50%
        upgradeInfo[18] = Upgrade(18, 0, 0.2 ether, 0, 6, 2); // +2
        
        upgradeInfo[19] = Upgrade(13, 50000, 0, 0, 7, 2); // +2
        upgradeInfo[20] = Upgrade(20, 0, 0.2 ether, 1, 7, 5); // 5 = +50%
        upgradeInfo[21] = Upgrade(21, 100000, 0, 1, 7, 5); // 5 = +50%
        
        upgradeInfo[22] = Upgrade(22, 0, 0.1 ether, 0, 8, 2); // +1
        upgradeInfo[23] = Upgrade(23, 25000, 0, 1, 8, 5); // 10 = +50%
        upgradeInfo[24] = Upgrade(24, 0, 0.2 ether, 0, 8, 4); // +2
        
        
        
        upgradeInfo[25] = Upgrade(25, 500, 0, 2, 40, 10); // +10
        upgradeInfo[26] = Upgrade(26, 0, 0.1 ether, 4, 40, 10); // +10
        upgradeInfo[27] = Upgrade(27, 10000, 0, 6, 40, 10); // +10
        
        upgradeInfo[28] = Upgrade(28, 0, 0.2 ether, 3, 41, 5); // +50 %
        upgradeInfo[29] = Upgrade(29, 5000, 0, 4, 41, 10); // +10
        upgradeInfo[30] = Upgrade(30, 0, 0.5 ether, 6, 41, 4); // +4
        
        upgradeInfo[31] = Upgrade(31, 2500, 0, 5, 42, 5); // +50 %
        upgradeInfo[32] = Upgrade(32, 0, 0.2 ether, 6, 42, 10); // +10
        upgradeInfo[33] = Upgrade(33, 20000, 0, 7, 42, 5); // +50 %
        
        upgradeInfo[34] = Upgrade(34, 0, 0.1 ether, 2, 43, 5); // +5
        upgradeInfo[35] = Upgrade(35, 10000, 0, 4, 43, 5); // +5
        upgradeInfo[36] = Upgrade(36, 0, 0.2 ether, 5, 43, 5); // +50%
        
        upgradeInfo[37] = Upgrade(37, 0, 0.1 ether, 2, 44, 15); // +15
        upgradeInfo[38] = Upgrade(38, 25000, 0, 3, 44, 5); // +50%
        upgradeInfo[39] = Upgrade(39, 0, 0.2 ether, 4, 44, 15); // +15
        
        upgradeInfo[40] = Upgrade(40, 50000, 0, 6, 45, 500); // +500
        upgradeInfo[41] = Upgrade(41, 0, 0.5 ether, 7, 45, 10); // +100 %
        upgradeInfo[42] = Upgrade(42, 250000, 0, 7, 45, 5); // +50 %
    
        
        rareInfo[1] = Rare(1, 0.5 ether, 1, 1, 30); // 30 = +300%
        rareInfo[2] = Rare(2, 0.5 ether, 0, 2, 4); // +4
    }
    
    function getGooCostForUnit(uint256 unitId, uint256 existing, uint256 amount) public constant returns (uint256) {
        if (amount == 1) { // 1
            if (existing == 0) {
                return unitInfo[unitId].baseGooCost;
            } else {
                return unitInfo[unitId].baseGooCost + (existing * unitInfo[unitId].gooCostIncreaseHalf * 2);
            }
        } else if (amount > 1) {
            uint256 existingCost;
            if (existing > 0) {
                existingCost = (unitInfo[unitId].baseGooCost * existing) + (existing * (existing - 1) * unitInfo[unitId].gooCostIncreaseHalf);
            }
            
            existing += amount;
            uint256 newCost = SafeMath.add(SafeMath.mul(unitInfo[unitId].baseGooCost, existing), SafeMath.mul(SafeMath.mul(existing, (existing - 1)), unitInfo[unitId].gooCostIncreaseHalf));
            return newCost - existingCost;
        }
    }
    
    function getWeakenedDefensePower(uint256 defendingPower) external constant returns (uint256) {
        return defendingPower / 2;
    }
    
    function validUnitId(uint256 unitId) external constant returns (bool) {
        return ((unitId > 0 && unitId < 9) || (unitId > 39 && unitId < 46));
    }
    
    function validUpgradeId(uint256 upgradeId) external constant returns (bool) {
        return (upgradeId > 0 && upgradeId < 43);
    }
    
    function validRareId(uint256 rareId) external constant returns (bool) {
        return (rareId > 0 && rareId < 3);
    }
    
    function unitEthCost(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].ethCost;
    }
    
    function unitGooProduction(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].baseGooProduction;
    }
    
    function unitAttack(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].attackValue;
    }
    
    function unitDefense(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].defenseValue;
    }
    
    function unitStealingCapacity(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].gooStealingCapacity;
    }
    
    function rareStartPrice(uint256 rareId) external constant returns (uint256) {
        return rareInfo[rareId].ethCost;
    }
    
    function productionUnitIdRange() external constant returns (uint256, uint256) {
        return (1, 8);
    }
    
    function battleUnitIdRange() external constant returns (uint256, uint256) {
        return (40, 45);
    }
    
    function upgradeIdRange() external constant returns (uint256, uint256) {
        return (1, 42);
    }
    
    function rareIdRange() external constant returns (uint256, uint256) {
        return (1, 2);
    }
    
    function getUpgradeInfo(uint256 upgradeId) external constant returns (uint256, uint256, uint256, uint256, uint256) {
        return (upgradeInfo[upgradeId].gooCost, upgradeInfo[upgradeId].ethCost, upgradeInfo[upgradeId].upgradeClass,
        upgradeInfo[upgradeId].unitId, upgradeInfo[upgradeId].upgradeValue);
    }
    
    function getRareInfo(uint256 rareId) external constant returns (uint256, uint256, uint256) {
        return (rareInfo[rareId].rareClass, rareInfo[rareId].unitId, rareInfo[rareId].rareValue);
    }
    
}

library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 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 c;
  }

  /**
  * @dev Substracts 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) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

Contract Security Audit

Contract ABI

API
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"approvee","type":"address"},{"name":"amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"totalGooProductionSnapshots","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGameInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256[]"},{"name":"","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"etherBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getGooProduction","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"player","type":"address"},{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"firstDivsTime","type":"uint256"}],"name":"beginGame","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getPlayersTickets","outputs":[{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"buyBasicUnit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"lastGooProductionUpdate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalEtherGooResearchPool","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLatestRaffleInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"checkWinner","type":"address"},{"name":"checkIndex","type":"uint256"}],"name":"awardRafflePrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"viewUnclaimedResearchDividends","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"target","type":"address"}],"name":"attackPlayer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gameStarted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"allocatedGooResearchSnapshots","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"exchange","type":"address"},{"name":"isProtected","type":"bool"}],"name":"protectAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"sellUnit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"raffleId","type":"uint256"}],"name":"getRafflePlayers","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSchemaAddress","type":"address"}],"name":"updateGooConfig","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalGooProduction","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getPlayersBattleStats","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"referer","type":"address"},{"name":"startSnapshot","type":"uint256"},{"name":"endSnapShot","type":"uint256"}],"name":"claimResearchDividends","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"rareId","type":"uint256"}],"name":"buyRareItem","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"upgradeId","type":"uint256"}],"name":"buyUpgrade","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"nextSnapshotTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRareItemInfo","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"buyRaffleTicket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"drawRandomWinner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"snapshotDailyGooResearchFunding","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"buyEthUnit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"endTime","type":"uint256"},{"name":"rareId","type":"uint256"}],"name":"startRareRaffle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"},{"name":"approvee","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"player","type":"address"},{"indexed":false,"name":"unitId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"UnitBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"player","type":"address"},{"indexed":false,"name":"unitId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"UnitSold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"attacker","type":"address"},{"indexed":false,"name":"target","type":"address"},{"indexed":false,"name":"success","type":"bool"},{"indexed":false,"name":"gooStolen","type":"uint256"}],"name":"PlayerAttacked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenOwner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Approval","type":"event"}]

60606040526103e760075560028054600160a060020a033316600160a060020a031991821617909155602580549091167321912e81d7eff8bff895302b45da76f7f070e3b91790556146dd806100566000396000f3006060604052600436106101ea5763ffffffff60e060020a60003504166306fdde0381146101ec578063095ea7b31461027657806313e3a4bc146102ac5780631746bd1b146102d4578063179fc99f146103b157806318160ddd146103d057806319e9e5de146103e357806323b872dd1461040257806325a7650a1461042a5780632693c150146104355780632bfd2e06146104ed5780633081fe3f14610506578063313ce5671461052557806338198c651461054e5780633bed33ce14610561578063431dbd9e1461057757806349c9dcf5146105c45780634efdd4f9146105e65780635dc22cce1461061d5780635e123ce41461063c578063616af9341461064f57806370a082311461066557806370bc52fb14610684578063751fef65146106a8578063789a12fd146106c15780637c85a7571461072a5780637ef58e731461074957806380fa79021461075c5780638da5cb5b1461077b5780638fafb286146107aa57806395d89b41146107cf5780639e30dd5f146107e2578063a5a2cb19146107ed578063a89cdad9146107f8578063a9059cbb1461080b578063b1d660031461082d578063b9de1c4114610840578063c2de290914610856578063c38f074114610869578063d8737d8a1461087c578063da7d57f91461088a578063dd62ed3e146108a3575b005b34156101f757600080fd5b6101ff6108c8565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561023b578082015183820152602001610223565b50505050905090810190601f1680156102685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561028157600080fd5b610298600160a060020a03600435166024356108ff565b604051901515815260200160405180910390f35b34156102b757600080fd5b6102c260043561096b565b60405190815260200160405180910390f35b34156102df57600080fd5b6102e761098a565b604051808a81526020018981526020018881526020018781526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561035557808201518382015260200161033d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561039457808201518382015260200161037c565b505050509050019b50505050505050505050505060405180910390f35b34156103bc57600080fd5b6102c2600160a060020a0360043516610d1b565b34156103db57600080fd5b6102c2610d3a565b34156103ee57600080fd5b6102c2600160a060020a0360043516610d41565b341561040d57600080fd5b610298600160a060020a0360043581169060243516604435610d6e565b6101ea600435610e60565b341561044057600080fd5b610454600160a060020a0360043516610ebf565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610498578082015183820152602001610480565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156104d75780820151838201526020016104bf565b5050505090500194505050505060405180910390f35b34156104f857600080fd5b6101ea600435602435610fe5565b341561051157600080fd5b6102c2600160a060020a03600435166112bf565b341561053057600080fd5b6105386112d1565b60405160ff909116815260200160405180910390f35b341561055957600080fd5b6102c26112d6565b341561056c57600080fd5b6101ea6004356112dc565b341561058257600080fd5b61058a61134c565b6040519485526020850193909352604080850192909252600160a060020a03166060840152608083019190915260a0909101905180910390f35b34156105cf57600080fd5b6101ea600160a060020a036004351660243561136c565b34156105f157600080fd5b6105f96115c0565b60405180848152602001838152602001828152602001935050505060405180910390f35b341561062857600080fd5b6101ea600160a060020a03600435166116c2565b341561064757600080fd5b610298611a29565b341561065a57600080fd5b6102c2600435611a39565b341561067057600080fd5b6102c2600160a060020a0360043516611a47565b341561068f57600080fd5b6101ea600160a060020a03600435166024351515611a73565b34156106b357600080fd5b6101ea600435602435611acc565b34156106cc57600080fd5b6106d7600435611dba565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107165780820151838201526020016106fe565b505050509050019250505060405180910390f35b341561073557600080fd5b6101ea600160a060020a0360043516611e35565b341561075457600080fd5b6102c2611e97565b341561076757600080fd5b6105f9600160a060020a0360043516611e9d565b341561078657600080fd5b61078e611fcd565b604051600160a060020a03909116815260200160405180910390f35b34156107b557600080fd5b6101ea600160a060020a0360043516602435604435611fdc565b34156107da57600080fd5b6101ff612230565b6101ea600435612267565b6101ea6004356124c9565b341561080357600080fd5b6102c26126fe565b341561081657600080fd5b610298600160a060020a0360043516602435612704565b341561083857600080fd5b6104546127a2565b341561084b57600080fd5b6101ea600435612997565b341561086157600080fd5b6101ea612aef565b341561087457600080fd5b6101ea612b76565b6101ea600435602435612bf9565b341561089557600080fd5b6101ea600435602435612f62565b34156108ae57600080fd5b6102c2600160a060020a036004358116906024351661303e565b60408051908101604052600781527f49646c6545746800000000000000000000000000000000000000000000000000602082015281565b600160a060020a033381166000818152601c6020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b600480548290811061097957fe5b600091825260209091200154905081565b600080600080600080600061099d614611565b6109a5614611565b6109ad614611565b6109b5614611565b60255460009081908190600160a060020a0316638975e45f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156109fb57600080fd5b5af11515610a0857600080fd5b50505060405180519050604051805910610a1f5750595b9080825280602002602001820160405250602554909550600160a060020a031663f10a98486040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515610a7257600080fd5b5af11515610a7f57600080fd5b50505060405180519050604051805910610a965750595b9080825280602002602001820160405250602554909450600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610ae857600080fd5b5af11515610af557600080fd5b5050506040518051906020018051919450909250505b818311610b5857600160a060020a0333166000908152601060209081526040808320868452909152902054858281518110610b4257fe5b6020908102909101015260019283019201610b0b565b602554600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610b9657600080fd5b5af11515610ba357600080fd5b5050506040518051906020018051919450909250505b818311610c0657600160a060020a0333166000908152601060209081526040808320868452909152902054858281518110610bf057fe5b6020908102909101015260019283019201610bb9565b50602554600090600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610c4857600080fd5b5af11515610c5557600080fd5b5050506040518051906020018051919450909250505b818311610cc057600160a060020a033316600090815260116020908152604080832086845290915290205460ff16848281518110610ca557fe5b91151560209283029091019091015260019283019201610c6b565b42600354600154600654610cd333611a47565b33600160a060020a03811660009081526008602052604090205490610cf790610d41565b8b8b9d509d509d509d509d509d509d509d509d505050505050909192939495969798565b600160a060020a0381166000908152600860205260409020545b919050565b6000545b90565b600160a060020a03166000908152600a60209081526040808320600d835281842054845290915290205490565b6000610d7984613069565b600160a060020a038085166000908152601c6020908152604080832033909416835292905220548211801590610dc75750600160a060020a0333166000908152600960205260409020548211155b1515610dd257600080fd5b600160a060020a03808516600081815260096020908152604080832080548890039055878516808452818420805489019055848452601c83528184203390961684529490915290819020805486900390557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b60025433600160a060020a03908116911614610e7b57600080fd5b60025460a060020a900460ff1615610e9257600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a17905560065534600355565b610ec7614611565b610ecf614611565b6000610ed9614611565b610ee1614611565b600160a060020a0386166000908152601e6020526040812060215460028201549195501415610fd9578360010154604051805910610f1c5750595b908082528060200260200182016040525092508360010154604051805910610f415750595b90808252806020026020018201604052509150600090505b8360010154811015610fd9578354849082908110610f7357fe5b906000526020600020906002020160000154838281518110610f9157fe5b602090810290910101528354849082908110610fa957fe5b906000526020600020906002020160010154828281518110610fc757fe5b60209081029091010152600101610f59565b50909590945092505050565b60025460009060a060020a900460ff16151561100057600080fd5b602554600160a060020a0316634677fe538460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561104857600080fd5b5af1151561105557600080fd5b50505060405180519050151561106a57600080fd5b600754600160a060020a03331660009081526010602090815260408083208784529091529020548301111561109e57600080fd5b602554600160a060020a03338116600090815260106020908152604080832088845290915290819020549190921691633837e9bd91869186905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b151561111857600080fd5b5af1151561112557600080fd5b5050506040518051905090508061113b33611a47565b101561114657600080fd5b602554600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561118e57600080fd5b5af1151561119b57600080fd5b50505060405180511590506111af57600080fd5b6111b933826130ab565b602554600090600160a060020a031663c46e3e858560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561120457600080fd5b5af1151561121157600080fd5b5050506040518051905011156112345761123461122f33858561313e565b6131f0565b33600160a060020a0381166000908152601060209081526040808320878452909152908190208054850190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b919085908590518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050565b600d6020526000908152604090205481565b600081565b60035481565b600160a060020a03331660009081526008602052604090205481111561130157600080fd5b600160a060020a033316600081815260086020526040908190208054849003905582156108fc0290839051600060405180830381858888f19350505050151561134957600080fd5b50565b602054602154602254602354602454600160a060020a0390911691929394565b6000806000806000806000804260205410151561138857600080fd5b602354600160a060020a03161561139e57600080fd5b602154600090815260126020526040902054600160a060020a0316156113c357600080fd5b60235460a060020a900460ff1615156113de576113de612aef565b600160a060020a038a161561148057600160a060020a038a166000908152601e60205260408120600181015490995011801561141d5750876001015489105b801561142e57506021548860020154145b1561148057875488908a90811061144157fe5b9060005260206000209060020201965086600001546024541015801561146d5750866001015460245411155b156114805761147b8a613241565b6115b4565b600095505b6021546000908152601f60205260409020548610156115b4576021546000908152601f602052604090208054879081106114bb57fe5b6000918252602080832090910154600160a060020a0316808352601e909152604082206001810154815492985090965060001901945085919081106114fc57fe5b906000526020600020906002020160000154602454101580156115405750835484908490811061152857fe5b90600052602060002090600202016001015460245411155b156115a957600091505b83600101548210156115a957835484908390811061156457fe5b906000526020600020906002020190508060000154602454101580156115905750806001015460245411155b1561159e5761147b85613241565b60019091019061154a565b600190950194611485565b50505050505050505050565b600160a060020a0333166000908152600e6020908152604080832054600554600a8452828520600019808401875294529184205484938493019083908382805b8583116116b1575050600160a060020a0333166000818152600a60209081526040808320858452825280832054938352600b825280832085845290915290205460ff168115801561164f575080155b1561165c57839150611660565b8193505b600480548490811061166e57fe5b9060005260206000209001548260058581548110151561168a57fe5b906000526020600020900154028115156116a057fe5b049490940193600190920191611600565b509298949750929550929350505050565b600160a060020a0333166000908152600f6020526040812054819081908190819081904290106116f157600080fd5b33600160a060020a031687600160a060020a03161415151561171257600080fd5b600160a060020a0387166000908152601d602052604090205460ff161561173857600080fd5b61174233886133a5565b600160a060020a038a166000908152600f60205260409020549298509096509450429011156117cc57602554600160a060020a03166394b67b1c8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156117b357600080fd5b5af115156117c057600080fd5b50505060405180519550505b848611156119a357600160a060020a0333166000908152600f6020526040902061070842019055836117fd88611a47565b11156118ea5761180c876134d6565b92508284111561184157600160a060020a03871660009081526009602052604090208054848603908190039091559150611866565b50600160a060020a038616600090815260096020526040902080548484039081019091555b33600160a060020a038116600090815260096020526040908190208054870190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f91908990600190889051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611983565b7fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f338860016119188b611a47565b604051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a161195787611a47565b600160a060020a0333811660009081526009602052604080822080549094019093559089168152908120555b600160a060020a0387166000908152600c60205260409020429055611a20565b33600160a060020a0381166000908152600f6020526040808220426102580190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f92918a91819051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a15b50505050505050565b60025460a060020a900460ff1681565b600580548290811061097957fe5b6000611a52826134d6565b600160a060020a038316600090815260096020526040902054019050919050565b60025433600160a060020a03908116911614611a8e57600080fd5b611a9782610d41565b15611aa157600080fd5b600160a060020a03919091166000908152601d60205260409020805460ff1916911515919091179055565b600160a060020a0333166000908152601060209081526040808320858452909152812054819083901015611aff57600080fd5b600160a060020a033381166000908152601060209081526040808320888452909152908190208054869003908190556025546004931691633837e9bd91889188905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b1515611b8157600080fd5b5af11515611b8e57600080fd5b50505060405180519050600302811515611ba457fe5b04915081611bb1336134d6565b600160a060020a033381166000908152600c6020908152604080832042905582549590940194850182556009905282812080548501905560255493945092169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611c2d57600080fd5b5af11515611c3a57600080fd5b505050604051805190501115611c5e57611c5e33611c5933878761313e565b61354f565b602554600090600160a060020a031663ee9cebde8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611ca957600080fd5b5af11515611cb657600080fd5b505050604051805190501115611d5b576025546004908490600160a060020a031663ee9cebde8760405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611d1357600080fd5b5af11515611d2057600080fd5b5050506040518051905002600302811515611d3757fe5b33600160a060020a0316600090815260086020526040902080549290910490910190555b7f9c8076df639d56f1ef3ca3d4d8dc6ed089f8c4756bc5bf5d574f1cec4ef13c543385856040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a150505050565b611dc2614611565b601f6000838152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015611e2957602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611e0b575b50505050509050919050565b60025460009033600160a060020a03908116911614611e5357600080fd5b5080611e5e81613613565b611e6781613bb9565b6025805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905550565b60015481565b6025546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515611eec57600080fd5b5af11515611ef957600080fd5b5050506040518051906020018051919650909450505b838511611fbe57600160a060020a0389166000908152601060209081526040808320888452909152902054611f47908a908790613f05565b600160a060020a038a166000908152601060209081526040808320898452909152902054930192611f7b908a908790613f8a565b600160a060020a038a166000908152601060209081526040808320898452909152902054910190611faf908a90879061400f565b60019095019490910190611f0f565b91989097509095509350505050565b600254600160a060020a031681565b6000808080808086881115611ff057600080fd5b600160a060020a0333166000908152600e602052604090205488101561201557600080fd5b600554871061202357600080fd5b600160a060020a0333166000908152600a60209081526040808320600e83528184205460001901845290915290205494508793505b86841161210c57600160a060020a0333166000818152600a60209081526040808320888452825280832054938352600b825280832088845290915290205490935060ff169150821580156120aa575081155b156120b7578492506120bb565b8294505b60048054859081106120c957fe5b906000526020600020900154836005868154811015156120e557fe5b906000526020600020900154028115156120fb57fe5b049590950194600190930192612058565b600160a060020a0333166000908152600a602090815260408083208a84529091529020541580156121615750600160a060020a0333166000908152600b6020908152604080832087845290915290205460ff16155b801561216d5750600085115b1561219957600160a060020a0333166000908152600a602090815260408083208a845290915290208590555b600160a060020a033381166000908152600e602052604090206001890190558916158015906121da575033600160a060020a031689600160a060020a031614155b156122055750600160a060020a03881660009081526008602052604090208054606487049081019091555b600160a060020a03331660009081526008602052604090208054919096030190945550505050505050565b60408051908101604052600381527f476f6f0000000000000000000000000000000000000000000000000000000000602082015281565b602554600090819081908190819081908190600160a060020a03166297b6078960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156122bd57600080fd5b5af115156122ca57600080fd5b5050506040518051905015156122df57600080fd5b600088815260126020526040902054600160a060020a0316965086151561230557600080fd5b600088815260136020908152604080832054600160a060020a033316845260089092529091205490965034018690101561233e57600080fd5b61234733613069565b602554600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561238f57600080fd5b5af1151561239c57600080fd5b50505060405180519060200180519060200180519297509095509093506123c7905033868686614094565b6123d087613069565b6123dc8786868661432d565b3486111561240a57600160a060020a0333166000908152600860205260409020805434880390039055612434565b8534111561243457600160a060020a03331660009081526008602052604090208054348890030190555b50506003805460148604908101909155600254600160a060020a039081166000908152600860208181526040808420805460328c049081019091559b845260128252808420805473ffffffffffffffffffffffffffffffffffffffff191633871617905560138252808420600460058c0204905599909316825290915295909520805496909501909303909401909255505050565b600080600080600080600260149054906101000a900460ff1615156124ed57600080fd5b602554600160a060020a03166347751b988860405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561253557600080fd5b5af1151561254257600080fd5b50505060405180519050151561255757600080fd5b600160a060020a03331660009081526011602090815260408083208a845290915290205460ff161561258857600080fd5b602554600160a060020a03166328a42e9d8860405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b15156125d057600080fd5b5af115156125dd57600080fd5b5050506040518051906020018051906020018051906020018051906020018051949a50929850909650945090925086905061261733611a47565b101561262257600080fd5b60008511156126b057600160a060020a03331660009081526008602052604090205434018590101561265357600080fd5b3485111561267d57600160a060020a03331660009081526008602052604090208054348703900390555b506003805460328604808703909101909155600254600160a060020a031660009081526008602052604090208054820190555b6126ba33876130ab565b6126c633858585614094565b505050600160a060020a033316600090815260116020908152604080832096835295905293909320805460ff19166001179055505050565b60065481565b600061270f33613069565b600160a060020a03331660009081526009602052604090205482111561273457600080fd5b600160a060020a033381166000818152600960205260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b6127aa614611565b6127b2614611565b6127ba614611565b6127c2614611565b60255460009081908190600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561280857600080fd5b5af1151561281557600080fd5b5050506040518051905060405180591061282c5750595b9080825280602002602001820160405250602554909550600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561287f57600080fd5b5af1151561288c57600080fd5b505050604051805190506040518059106128a35750595b9080825280602002602001820160405250602554909450600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156128f557600080fd5b5af1151561290257600080fd5b5050506040518051906020018051919450909250505b81831161298a57600083815260126020526040902054600160a060020a031685828151811061294357fe5b600160a060020a03909216602092830290910182015260008481526013909152604090205484828151811061297457fe5b6020908102909101015260019283019201612918565b5092959194509092505050565b60008042602054101515156129ab57600080fd5b600083116129b857600080fd5b6129c46103e8846145c9565b9150816129d033611a47565b10156129db57600080fd5b6129e533836130ab565b50600160a060020a0333166000908152601e60205260409020602154600282015414612a6e5760006001808301829055602154600284018190558252601f6020526040909120805490918101612a3b8382614623565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b805460018201541415612a8c578054600101612a8a8282614647565b505b60408051908101604052602254808252840160001901602082015260018281018054918201905582548391908110612ac057fe5b906000526020600020906002020160008201518155602082015160019091015550506022805490920190915550565b60025460009033600160a060020a03908116911614612b0d57600080fd5b602054429010612b1c57600080fd5b60235460a060020a900460ff1615612b3357600080fd5b5060225442810190801515612b4457fe5b8160001943014008602455506023805474ff0000000000000000000000000000000000000000191660a060020a179055565b60025460009033600160a060020a03908116911614612b9457600080fd5b5060038054600a8104908190039091556004805460018101612bb68382614623565b916000526020600020900160006001549091909150555060058054806001018281612be19190614623565b50600091825260209091200155620151804201600655565b600080600080600260149054906101000a900460ff161515612c1a57600080fd5b602554600160a060020a0316634677fe538760405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612c6257600080fd5b5af11515612c6f57600080fd5b505050604051805190501515612c8457600080fd5b600754600160a060020a03331660009081526010602090815260408083208a845290915290205486011115612cb857600080fd5b602554600160a060020a0333811660009081526010602090815260408083208b845290915290819020549190921691633837e9bd91899189905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b1515612d3257600080fd5b5af11515612d3f57600080fd5b5050506040518051602554909550612db49150600160a060020a031663ee9cebde8860405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612d9757600080fd5b5af11515612da457600080fd5b50505060405180519050866145c9565b925083612dc033611a47565b1015612dcb57600080fd5b600160a060020a033316600090815260086020526040902054340183901015612df357600080fd5b612dfd33856130ab565b34831115612e2757600160a060020a03331660009081526008602052604090208054348503900390555b50506003805460046032840480850391909104918201909255600254600160a060020a039081166000908152600860205260408082208054860190556025549192919091169063c46e3e859089905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612ea957600080fd5b5af11515612eb657600080fd5b505050604051805190501115612ed457612ed461122f33888861313e565b33600160a060020a03811660009081526010602090815260408083208a8452909152908190208054880190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b919088908890518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050505050565b60025433600160a060020a03908116911614612f7d57600080fd5b602554600160a060020a03166297b6078260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612fc457600080fd5b5af11515612fd157600080fd5b505050604051805190501515612fe657600080fd5b600081815260126020526040902054600160a060020a03161561300857600080fd5b602380546000602481905574ffffffffffffffffffffffffffffffffffffffffff19909116909155602255602091909155602155565b600160a060020a039182166000908152601c6020908152604080832093909416825291909152205490565b6000613074826134d6565b600160a060020a039092166000908152600c6020908152604080832042905582548501835560099091529020805490920190915550565b60008060006130b9856134d6565b9250828411156130f45760008054848603908190038255600160a060020a03871682526009602052604090912080548290039055915061311e565b50600080548484039081018255600160a060020a0386168252600960205260409091208054820190555b50505050600160a060020a03166000908152600c60205260409020429055565b600160a060020a03808416600081815260156020908152604080832087845282528083205493835260148252808320878452909152808220546025549294600a94850193919291169063c46e3e859088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b5af115156131d057600080fd5b50505060405180519050018402028115156131e757fe5b04949350505050565b806131fa33610d41565b600160a060020a0333166000818152600a60209081526040808320600580548552908352818420969095019095559254918152600d90925291902055600180549091019055565b60238054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283168117909355602180546000908152601260205260408082208054909516909517909355602554905492938493849360149316916357f1f6ca91905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156132d757600080fd5b5af115156132e457600080fd5b505050604051805190506015028115156132fa57fe5b6021546000908152601360205260409020919004905561331984613069565b602554602154600160a060020a039091169063275babee9060405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561336757600080fd5b5af1151561337457600080fd5b505050604051805190602001805190602001805192955090935090915061339f905084848484614094565b50505050565b6025546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156133f457600080fd5b5af1151561340157600080fd5b5050506040518051906020018051919650909450505b8385116134c657600160a060020a038a16600090815260106020908152604080832088845290915290205461344f908b908790613f05565b600160a060020a038b166000908152601060209081526040808320898452909152902054930192613483908b908790613f8a565b600160a060020a038a1660009081526010602090815260408083208984529091529020549101906134b7908a90879061400f565b60019095019490910190613417565b9199909850909650945050505050565b600160a060020a0381166000908152600c602052604081205481901180156135165750600160a060020a0382166000908152600c60205260409020544290105b1561354757600160a060020a0382166000908152600c6020526040902054420361353f83610d41565b029050610d35565b506000919050565b60008061355b84610d41565b915061356782846145ff565b90508015156135bc57600160a060020a0384166000818152600b60209081526040808320600580548552908352818420805460ff19166001179055938352600a825280832093548352929052908120556135e5565b600160a060020a0384166000908152600a60209081526040808320600554845290915290208190555b5050600554600160a060020a039092166000908152600d602052604090209190915560018054919091039055565b6025546000908190600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561365657600080fd5b5af1151561366357600080fd5b5050506040518051906020018051919350909150505b80821161381d5782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156136c657600080fd5b5af115156136d357600080fd5b5050506040518051602554909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561372657600080fd5b5af1151561373357600080fd5b5050506040518051905014151561374957600080fd5b82600160a060020a031663c46e3e858360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561378f57600080fd5b5af1151561379c57600080fd5b5050506040518051602554909150600160a060020a031663c46e3e858460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156137ef57600080fd5b5af115156137fc57600080fd5b5050506040518051905014151561381257600080fd5b600190910190613679565b602554600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561385b57600080fd5b5af1151561386857600080fd5b5050506040518051906020018051919350909150505b808211613bb45782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156138cb57600080fd5b5af115156138d857600080fd5b5050506040518051602554909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561392b57600080fd5b5af1151561393857600080fd5b5050506040518051905014151561394e57600080fd5b82600160a060020a03166369632f568360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561399457600080fd5b5af115156139a157600080fd5b5050506040518051602554909150600160a060020a03166369632f568460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156139f457600080fd5b5af11515613a0157600080fd5b50505060405180519050141515613a1757600080fd5b82600160a060020a03166321446cfe8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613a5d57600080fd5b5af11515613a6a57600080fd5b5050506040518051602554909150600160a060020a03166321446cfe8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613abd57600080fd5b5af11515613aca57600080fd5b50505060405180519050141515613ae057600080fd5b82600160a060020a0316636101a1f78360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613b2657600080fd5b5af11515613b3357600080fd5b5050506040518051602554909150600160a060020a0316636101a1f78460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613b8657600080fd5b5af11515613b9357600080fd5b50505060405180519050141515613ba957600080fd5b60019091019061387e565b505050565b600080600080600080600080600080600080602560009054906101000a9004600160a060020a0316600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515613c1c57600080fd5b5af11515613c2957600080fd5b5050506040518051906020018051919d50909b50505b8a8c11613d7b57602554600160a060020a03166328a42e9d8d60405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b1515613c8e57600080fd5b5af11515613c9b57600080fd5b5050506040518051906020018051906020018051906020018051906020018051929e50909c50909a50919550935050600160a060020a038d166328a42e9d8d60405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b1515613d1057600080fd5b5af11515613d1d57600080fd5b5050506040518051906020018051906020018051906020018051906020018051929b50909950909750919350915050838214613d5857600080fd5b888614613d6457600080fd5b878514613d7057600080fd5b6001909b019a613c3f565b602554600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515613db957600080fd5b5af11515613dc657600080fd5b5050506040518051906020018051919d50909b50505b8a8c11613ef657602554600160a060020a031663275babee8d60405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b1515613e2b57600080fd5b5af11515613e3857600080fd5b5050506040518051906020018051906020018051929c50909a5090985050600160a060020a038d1663275babee8d60405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b1515613e9c57600080fd5b5af11515613ea957600080fd5b505050604051805190602001805190602001805192995090975090955050898714613ed357600080fd5b888614613edf57600080fd5b878514613eeb57600080fd5b6001909b019a613ddc565b50505050505050505050505050565b600160a060020a03808416600081815260176020908152604080832087845282528083205493835260168252808320878452909152808220546025549294600a9485019391929116906369632f569088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600160a060020a038084166000818152601b60209081526040808320878452825280832054938352601a8252808320878452909152808220546025549294600a948501939192911690636101a1f79088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600160a060020a03808416600081815260196020908152604080832087845282528083205493835260188252808320878452909152808220546025549294600a9485019391929116906321446cfe9088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600083151561410757600160a060020a038516600081815260146020908152604080832087845282528083208054870190558383526015825280832087845282528083205493835260108252808320878452909152902054600a918201908402025b049050614102816131f0565b614326565b83600114156141e057600160a060020a038086166000818152601560209081526040808320888452825280832080548801905592825260148152828220878352905281902054602554600a93919291169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561419457600080fd5b5af115156141a157600080fd5b5050506040518051600160a060020a03891660009081526010602090815260408083208a8452909152902054860292019190910290508115156140f657fe5b836002141561421757600160a060020a03851660009081526016602090815260408083208684529091529020805483019055614326565b836003141561424e57600160a060020a03851660009081526017602090815260408083208684529091529020805483019055614326565b836004141561428557600160a060020a03851660009081526018602090815260408083208684529091529020805483019055614326565b83600514156142bc57600160a060020a03851660009081526019602090815260408083208684529091529020805483019055614326565b83600614156142f357600160a060020a0385166000908152601a602090815260408083208684529091529020805483019055614326565b836007141561432657600160a060020a0385166000908152601b6020908152604080832086845290915290208054830190555b5050505050565b600083151561439d57600160a060020a03851660008181526014602090815260408083208784528252808320805487900390558383526015825280832087845282528083205493835260108252808320878452909152902054600a918201908402025b049050614102858261354f565b836001141561447757600160a060020a03808616600081815260156020908152604080832088845282528083208054889003905592825260148152828220878352905281902054602554600a93919291169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561442b57600080fd5b5af1151561443857600080fd5b5050506040518051600160a060020a03891660009081526010602090815260408083208a84529091529020548602920191909102905081151561439057fe5b83600214156144af57600160a060020a0385166000908152601660209081526040808320868452909152902080548390039055614326565b83600314156144e757600160a060020a0385166000908152601760209081526040808320868452909152902080548390039055614326565b836004141561451f57600160a060020a0385166000908152601860209081526040808320868452909152902080548390039055614326565b836005141561455757600160a060020a0385166000908152601960209081526040808320868452909152902080548390039055614326565b836006141561458f57600160a060020a0385166000908152601a60209081526040808320868452909152902080548390039055614326565b836007141561432657600160a060020a0385166000908152601b602090815260408083208684529091529020805483900390555050505050565b6000808315156145dc57600091506145f8565b508282028284828115156145ec57fe5b04146145f457fe5b8091505b5092915050565b60008282111561460b57fe5b50900390565b60206040519081016040526000815290565b815481835581811511613bb457600083815260209020613bb4918101908301614673565b815481835581811511613bb457600202816002028360005260206000209182019101613bb49190614691565b610d3e91905b8082111561468d5760008155600101614679565b5090565b610d3e91905b8082111561468d57600080825560018201556002016146975600a165627a7a72305820ae34a2e0cd26a642ebf0feb477e2acbd6179b8a4cc4ee64d8b8a0c232cd8af480029

Deployed Bytecode

0x6060604052600436106101ea5763ffffffff60e060020a60003504166306fdde0381146101ec578063095ea7b31461027657806313e3a4bc146102ac5780631746bd1b146102d4578063179fc99f146103b157806318160ddd146103d057806319e9e5de146103e357806323b872dd1461040257806325a7650a1461042a5780632693c150146104355780632bfd2e06146104ed5780633081fe3f14610506578063313ce5671461052557806338198c651461054e5780633bed33ce14610561578063431dbd9e1461057757806349c9dcf5146105c45780634efdd4f9146105e65780635dc22cce1461061d5780635e123ce41461063c578063616af9341461064f57806370a082311461066557806370bc52fb14610684578063751fef65146106a8578063789a12fd146106c15780637c85a7571461072a5780637ef58e731461074957806380fa79021461075c5780638da5cb5b1461077b5780638fafb286146107aa57806395d89b41146107cf5780639e30dd5f146107e2578063a5a2cb19146107ed578063a89cdad9146107f8578063a9059cbb1461080b578063b1d660031461082d578063b9de1c4114610840578063c2de290914610856578063c38f074114610869578063d8737d8a1461087c578063da7d57f91461088a578063dd62ed3e146108a3575b005b34156101f757600080fd5b6101ff6108c8565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561023b578082015183820152602001610223565b50505050905090810190601f1680156102685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561028157600080fd5b610298600160a060020a03600435166024356108ff565b604051901515815260200160405180910390f35b34156102b757600080fd5b6102c260043561096b565b60405190815260200160405180910390f35b34156102df57600080fd5b6102e761098a565b604051808a81526020018981526020018881526020018781526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561035557808201518382015260200161033d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561039457808201518382015260200161037c565b505050509050019b50505050505050505050505060405180910390f35b34156103bc57600080fd5b6102c2600160a060020a0360043516610d1b565b34156103db57600080fd5b6102c2610d3a565b34156103ee57600080fd5b6102c2600160a060020a0360043516610d41565b341561040d57600080fd5b610298600160a060020a0360043581169060243516604435610d6e565b6101ea600435610e60565b341561044057600080fd5b610454600160a060020a0360043516610ebf565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610498578082015183820152602001610480565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156104d75780820151838201526020016104bf565b5050505090500194505050505060405180910390f35b34156104f857600080fd5b6101ea600435602435610fe5565b341561051157600080fd5b6102c2600160a060020a03600435166112bf565b341561053057600080fd5b6105386112d1565b60405160ff909116815260200160405180910390f35b341561055957600080fd5b6102c26112d6565b341561056c57600080fd5b6101ea6004356112dc565b341561058257600080fd5b61058a61134c565b6040519485526020850193909352604080850192909252600160a060020a03166060840152608083019190915260a0909101905180910390f35b34156105cf57600080fd5b6101ea600160a060020a036004351660243561136c565b34156105f157600080fd5b6105f96115c0565b60405180848152602001838152602001828152602001935050505060405180910390f35b341561062857600080fd5b6101ea600160a060020a03600435166116c2565b341561064757600080fd5b610298611a29565b341561065a57600080fd5b6102c2600435611a39565b341561067057600080fd5b6102c2600160a060020a0360043516611a47565b341561068f57600080fd5b6101ea600160a060020a03600435166024351515611a73565b34156106b357600080fd5b6101ea600435602435611acc565b34156106cc57600080fd5b6106d7600435611dba565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107165780820151838201526020016106fe565b505050509050019250505060405180910390f35b341561073557600080fd5b6101ea600160a060020a0360043516611e35565b341561075457600080fd5b6102c2611e97565b341561076757600080fd5b6105f9600160a060020a0360043516611e9d565b341561078657600080fd5b61078e611fcd565b604051600160a060020a03909116815260200160405180910390f35b34156107b557600080fd5b6101ea600160a060020a0360043516602435604435611fdc565b34156107da57600080fd5b6101ff612230565b6101ea600435612267565b6101ea6004356124c9565b341561080357600080fd5b6102c26126fe565b341561081657600080fd5b610298600160a060020a0360043516602435612704565b341561083857600080fd5b6104546127a2565b341561084b57600080fd5b6101ea600435612997565b341561086157600080fd5b6101ea612aef565b341561087457600080fd5b6101ea612b76565b6101ea600435602435612bf9565b341561089557600080fd5b6101ea600435602435612f62565b34156108ae57600080fd5b6102c2600160a060020a036004358116906024351661303e565b60408051908101604052600781527f49646c6545746800000000000000000000000000000000000000000000000000602082015281565b600160a060020a033381166000818152601c6020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b600480548290811061097957fe5b600091825260209091200154905081565b600080600080600080600061099d614611565b6109a5614611565b6109ad614611565b6109b5614611565b60255460009081908190600160a060020a0316638975e45f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156109fb57600080fd5b5af11515610a0857600080fd5b50505060405180519050604051805910610a1f5750595b9080825280602002602001820160405250602554909550600160a060020a031663f10a98486040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515610a7257600080fd5b5af11515610a7f57600080fd5b50505060405180519050604051805910610a965750595b9080825280602002602001820160405250602554909450600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610ae857600080fd5b5af11515610af557600080fd5b5050506040518051906020018051919450909250505b818311610b5857600160a060020a0333166000908152601060209081526040808320868452909152902054858281518110610b4257fe5b6020908102909101015260019283019201610b0b565b602554600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610b9657600080fd5b5af11515610ba357600080fd5b5050506040518051906020018051919450909250505b818311610c0657600160a060020a0333166000908152601060209081526040808320868452909152902054858281518110610bf057fe5b6020908102909101015260019283019201610bb9565b50602554600090600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610c4857600080fd5b5af11515610c5557600080fd5b5050506040518051906020018051919450909250505b818311610cc057600160a060020a033316600090815260116020908152604080832086845290915290205460ff16848281518110610ca557fe5b91151560209283029091019091015260019283019201610c6b565b42600354600154600654610cd333611a47565b33600160a060020a03811660009081526008602052604090205490610cf790610d41565b8b8b9d509d509d509d509d509d509d509d509d505050505050909192939495969798565b600160a060020a0381166000908152600860205260409020545b919050565b6000545b90565b600160a060020a03166000908152600a60209081526040808320600d835281842054845290915290205490565b6000610d7984613069565b600160a060020a038085166000908152601c6020908152604080832033909416835292905220548211801590610dc75750600160a060020a0333166000908152600960205260409020548211155b1515610dd257600080fd5b600160a060020a03808516600081815260096020908152604080832080548890039055878516808452818420805489019055848452601c83528184203390961684529490915290819020805486900390557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b60025433600160a060020a03908116911614610e7b57600080fd5b60025460a060020a900460ff1615610e9257600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a17905560065534600355565b610ec7614611565b610ecf614611565b6000610ed9614611565b610ee1614611565b600160a060020a0386166000908152601e6020526040812060215460028201549195501415610fd9578360010154604051805910610f1c5750595b908082528060200260200182016040525092508360010154604051805910610f415750595b90808252806020026020018201604052509150600090505b8360010154811015610fd9578354849082908110610f7357fe5b906000526020600020906002020160000154838281518110610f9157fe5b602090810290910101528354849082908110610fa957fe5b906000526020600020906002020160010154828281518110610fc757fe5b60209081029091010152600101610f59565b50909590945092505050565b60025460009060a060020a900460ff16151561100057600080fd5b602554600160a060020a0316634677fe538460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561104857600080fd5b5af1151561105557600080fd5b50505060405180519050151561106a57600080fd5b600754600160a060020a03331660009081526010602090815260408083208784529091529020548301111561109e57600080fd5b602554600160a060020a03338116600090815260106020908152604080832088845290915290819020549190921691633837e9bd91869186905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b151561111857600080fd5b5af1151561112557600080fd5b5050506040518051905090508061113b33611a47565b101561114657600080fd5b602554600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561118e57600080fd5b5af1151561119b57600080fd5b50505060405180511590506111af57600080fd5b6111b933826130ab565b602554600090600160a060020a031663c46e3e858560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561120457600080fd5b5af1151561121157600080fd5b5050506040518051905011156112345761123461122f33858561313e565b6131f0565b33600160a060020a0381166000908152601060209081526040808320878452909152908190208054850190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b919085908590518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050565b600d6020526000908152604090205481565b600081565b60035481565b600160a060020a03331660009081526008602052604090205481111561130157600080fd5b600160a060020a033316600081815260086020526040908190208054849003905582156108fc0290839051600060405180830381858888f19350505050151561134957600080fd5b50565b602054602154602254602354602454600160a060020a0390911691929394565b6000806000806000806000804260205410151561138857600080fd5b602354600160a060020a03161561139e57600080fd5b602154600090815260126020526040902054600160a060020a0316156113c357600080fd5b60235460a060020a900460ff1615156113de576113de612aef565b600160a060020a038a161561148057600160a060020a038a166000908152601e60205260408120600181015490995011801561141d5750876001015489105b801561142e57506021548860020154145b1561148057875488908a90811061144157fe5b9060005260206000209060020201965086600001546024541015801561146d5750866001015460245411155b156114805761147b8a613241565b6115b4565b600095505b6021546000908152601f60205260409020548610156115b4576021546000908152601f602052604090208054879081106114bb57fe5b6000918252602080832090910154600160a060020a0316808352601e909152604082206001810154815492985090965060001901945085919081106114fc57fe5b906000526020600020906002020160000154602454101580156115405750835484908490811061152857fe5b90600052602060002090600202016001015460245411155b156115a957600091505b83600101548210156115a957835484908390811061156457fe5b906000526020600020906002020190508060000154602454101580156115905750806001015460245411155b1561159e5761147b85613241565b60019091019061154a565b600190950194611485565b50505050505050505050565b600160a060020a0333166000908152600e6020908152604080832054600554600a8452828520600019808401875294529184205484938493019083908382805b8583116116b1575050600160a060020a0333166000818152600a60209081526040808320858452825280832054938352600b825280832085845290915290205460ff168115801561164f575080155b1561165c57839150611660565b8193505b600480548490811061166e57fe5b9060005260206000209001548260058581548110151561168a57fe5b906000526020600020900154028115156116a057fe5b049490940193600190920191611600565b509298949750929550929350505050565b600160a060020a0333166000908152600f6020526040812054819081908190819081904290106116f157600080fd5b33600160a060020a031687600160a060020a03161415151561171257600080fd5b600160a060020a0387166000908152601d602052604090205460ff161561173857600080fd5b61174233886133a5565b600160a060020a038a166000908152600f60205260409020549298509096509450429011156117cc57602554600160a060020a03166394b67b1c8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156117b357600080fd5b5af115156117c057600080fd5b50505060405180519550505b848611156119a357600160a060020a0333166000908152600f6020526040902061070842019055836117fd88611a47565b11156118ea5761180c876134d6565b92508284111561184157600160a060020a03871660009081526009602052604090208054848603908190039091559150611866565b50600160a060020a038616600090815260096020526040902080548484039081019091555b33600160a060020a038116600090815260096020526040908190208054870190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f91908990600190889051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611983565b7fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f338860016119188b611a47565b604051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a161195787611a47565b600160a060020a0333811660009081526009602052604080822080549094019093559089168152908120555b600160a060020a0387166000908152600c60205260409020429055611a20565b33600160a060020a0381166000908152600f6020526040808220426102580190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f92918a91819051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a15b50505050505050565b60025460a060020a900460ff1681565b600580548290811061097957fe5b6000611a52826134d6565b600160a060020a038316600090815260096020526040902054019050919050565b60025433600160a060020a03908116911614611a8e57600080fd5b611a9782610d41565b15611aa157600080fd5b600160a060020a03919091166000908152601d60205260409020805460ff1916911515919091179055565b600160a060020a0333166000908152601060209081526040808320858452909152812054819083901015611aff57600080fd5b600160a060020a033381166000908152601060209081526040808320888452909152908190208054869003908190556025546004931691633837e9bd91889188905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b1515611b8157600080fd5b5af11515611b8e57600080fd5b50505060405180519050600302811515611ba457fe5b04915081611bb1336134d6565b600160a060020a033381166000908152600c6020908152604080832042905582549590940194850182556009905282812080548501905560255493945092169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611c2d57600080fd5b5af11515611c3a57600080fd5b505050604051805190501115611c5e57611c5e33611c5933878761313e565b61354f565b602554600090600160a060020a031663ee9cebde8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611ca957600080fd5b5af11515611cb657600080fd5b505050604051805190501115611d5b576025546004908490600160a060020a031663ee9cebde8760405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611d1357600080fd5b5af11515611d2057600080fd5b5050506040518051905002600302811515611d3757fe5b33600160a060020a0316600090815260086020526040902080549290910490910190555b7f9c8076df639d56f1ef3ca3d4d8dc6ed089f8c4756bc5bf5d574f1cec4ef13c543385856040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a150505050565b611dc2614611565b601f6000838152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015611e2957602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611e0b575b50505050509050919050565b60025460009033600160a060020a03908116911614611e5357600080fd5b5080611e5e81613613565b611e6781613bb9565b6025805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905550565b60015481565b6025546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515611eec57600080fd5b5af11515611ef957600080fd5b5050506040518051906020018051919650909450505b838511611fbe57600160a060020a0389166000908152601060209081526040808320888452909152902054611f47908a908790613f05565b600160a060020a038a166000908152601060209081526040808320898452909152902054930192611f7b908a908790613f8a565b600160a060020a038a166000908152601060209081526040808320898452909152902054910190611faf908a90879061400f565b60019095019490910190611f0f565b91989097509095509350505050565b600254600160a060020a031681565b6000808080808086881115611ff057600080fd5b600160a060020a0333166000908152600e602052604090205488101561201557600080fd5b600554871061202357600080fd5b600160a060020a0333166000908152600a60209081526040808320600e83528184205460001901845290915290205494508793505b86841161210c57600160a060020a0333166000818152600a60209081526040808320888452825280832054938352600b825280832088845290915290205490935060ff169150821580156120aa575081155b156120b7578492506120bb565b8294505b60048054859081106120c957fe5b906000526020600020900154836005868154811015156120e557fe5b906000526020600020900154028115156120fb57fe5b049590950194600190930192612058565b600160a060020a0333166000908152600a602090815260408083208a84529091529020541580156121615750600160a060020a0333166000908152600b6020908152604080832087845290915290205460ff16155b801561216d5750600085115b1561219957600160a060020a0333166000908152600a602090815260408083208a845290915290208590555b600160a060020a033381166000908152600e602052604090206001890190558916158015906121da575033600160a060020a031689600160a060020a031614155b156122055750600160a060020a03881660009081526008602052604090208054606487049081019091555b600160a060020a03331660009081526008602052604090208054919096030190945550505050505050565b60408051908101604052600381527f476f6f0000000000000000000000000000000000000000000000000000000000602082015281565b602554600090819081908190819081908190600160a060020a03166297b6078960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156122bd57600080fd5b5af115156122ca57600080fd5b5050506040518051905015156122df57600080fd5b600088815260126020526040902054600160a060020a0316965086151561230557600080fd5b600088815260136020908152604080832054600160a060020a033316845260089092529091205490965034018690101561233e57600080fd5b61234733613069565b602554600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561238f57600080fd5b5af1151561239c57600080fd5b50505060405180519060200180519060200180519297509095509093506123c7905033868686614094565b6123d087613069565b6123dc8786868661432d565b3486111561240a57600160a060020a0333166000908152600860205260409020805434880390039055612434565b8534111561243457600160a060020a03331660009081526008602052604090208054348890030190555b50506003805460148604908101909155600254600160a060020a039081166000908152600860208181526040808420805460328c049081019091559b845260128252808420805473ffffffffffffffffffffffffffffffffffffffff191633871617905560138252808420600460058c0204905599909316825290915295909520805496909501909303909401909255505050565b600080600080600080600260149054906101000a900460ff1615156124ed57600080fd5b602554600160a060020a03166347751b988860405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561253557600080fd5b5af1151561254257600080fd5b50505060405180519050151561255757600080fd5b600160a060020a03331660009081526011602090815260408083208a845290915290205460ff161561258857600080fd5b602554600160a060020a03166328a42e9d8860405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b15156125d057600080fd5b5af115156125dd57600080fd5b5050506040518051906020018051906020018051906020018051906020018051949a50929850909650945090925086905061261733611a47565b101561262257600080fd5b60008511156126b057600160a060020a03331660009081526008602052604090205434018590101561265357600080fd5b3485111561267d57600160a060020a03331660009081526008602052604090208054348703900390555b506003805460328604808703909101909155600254600160a060020a031660009081526008602052604090208054820190555b6126ba33876130ab565b6126c633858585614094565b505050600160a060020a033316600090815260116020908152604080832096835295905293909320805460ff19166001179055505050565b60065481565b600061270f33613069565b600160a060020a03331660009081526009602052604090205482111561273457600080fd5b600160a060020a033381166000818152600960205260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b6127aa614611565b6127b2614611565b6127ba614611565b6127c2614611565b60255460009081908190600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561280857600080fd5b5af1151561281557600080fd5b5050506040518051905060405180591061282c5750595b9080825280602002602001820160405250602554909550600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561287f57600080fd5b5af1151561288c57600080fd5b505050604051805190506040518059106128a35750595b9080825280602002602001820160405250602554909450600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156128f557600080fd5b5af1151561290257600080fd5b5050506040518051906020018051919450909250505b81831161298a57600083815260126020526040902054600160a060020a031685828151811061294357fe5b600160a060020a03909216602092830290910182015260008481526013909152604090205484828151811061297457fe5b6020908102909101015260019283019201612918565b5092959194509092505050565b60008042602054101515156129ab57600080fd5b600083116129b857600080fd5b6129c46103e8846145c9565b9150816129d033611a47565b10156129db57600080fd5b6129e533836130ab565b50600160a060020a0333166000908152601e60205260409020602154600282015414612a6e5760006001808301829055602154600284018190558252601f6020526040909120805490918101612a3b8382614623565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b805460018201541415612a8c578054600101612a8a8282614647565b505b60408051908101604052602254808252840160001901602082015260018281018054918201905582548391908110612ac057fe5b906000526020600020906002020160008201518155602082015160019091015550506022805490920190915550565b60025460009033600160a060020a03908116911614612b0d57600080fd5b602054429010612b1c57600080fd5b60235460a060020a900460ff1615612b3357600080fd5b5060225442810190801515612b4457fe5b8160001943014008602455506023805474ff0000000000000000000000000000000000000000191660a060020a179055565b60025460009033600160a060020a03908116911614612b9457600080fd5b5060038054600a8104908190039091556004805460018101612bb68382614623565b916000526020600020900160006001549091909150555060058054806001018281612be19190614623565b50600091825260209091200155620151804201600655565b600080600080600260149054906101000a900460ff161515612c1a57600080fd5b602554600160a060020a0316634677fe538760405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612c6257600080fd5b5af11515612c6f57600080fd5b505050604051805190501515612c8457600080fd5b600754600160a060020a03331660009081526010602090815260408083208a845290915290205486011115612cb857600080fd5b602554600160a060020a0333811660009081526010602090815260408083208b845290915290819020549190921691633837e9bd91899189905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b1515612d3257600080fd5b5af11515612d3f57600080fd5b5050506040518051602554909550612db49150600160a060020a031663ee9cebde8860405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612d9757600080fd5b5af11515612da457600080fd5b50505060405180519050866145c9565b925083612dc033611a47565b1015612dcb57600080fd5b600160a060020a033316600090815260086020526040902054340183901015612df357600080fd5b612dfd33856130ab565b34831115612e2757600160a060020a03331660009081526008602052604090208054348503900390555b50506003805460046032840480850391909104918201909255600254600160a060020a039081166000908152600860205260408082208054860190556025549192919091169063c46e3e859089905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612ea957600080fd5b5af11515612eb657600080fd5b505050604051805190501115612ed457612ed461122f33888861313e565b33600160a060020a03811660009081526010602090815260408083208a8452909152908190208054880190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b919088908890518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050505050565b60025433600160a060020a03908116911614612f7d57600080fd5b602554600160a060020a03166297b6078260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612fc457600080fd5b5af11515612fd157600080fd5b505050604051805190501515612fe657600080fd5b600081815260126020526040902054600160a060020a03161561300857600080fd5b602380546000602481905574ffffffffffffffffffffffffffffffffffffffffff19909116909155602255602091909155602155565b600160a060020a039182166000908152601c6020908152604080832093909416825291909152205490565b6000613074826134d6565b600160a060020a039092166000908152600c6020908152604080832042905582548501835560099091529020805490920190915550565b60008060006130b9856134d6565b9250828411156130f45760008054848603908190038255600160a060020a03871682526009602052604090912080548290039055915061311e565b50600080548484039081018255600160a060020a0386168252600960205260409091208054820190555b50505050600160a060020a03166000908152600c60205260409020429055565b600160a060020a03808416600081815260156020908152604080832087845282528083205493835260148252808320878452909152808220546025549294600a94850193919291169063c46e3e859088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b5af115156131d057600080fd5b50505060405180519050018402028115156131e757fe5b04949350505050565b806131fa33610d41565b600160a060020a0333166000818152600a60209081526040808320600580548552908352818420969095019095559254918152600d90925291902055600180549091019055565b60238054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283168117909355602180546000908152601260205260408082208054909516909517909355602554905492938493849360149316916357f1f6ca91905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156132d757600080fd5b5af115156132e457600080fd5b505050604051805190506015028115156132fa57fe5b6021546000908152601360205260409020919004905561331984613069565b602554602154600160a060020a039091169063275babee9060405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561336757600080fd5b5af1151561337457600080fd5b505050604051805190602001805190602001805192955090935090915061339f905084848484614094565b50505050565b6025546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156133f457600080fd5b5af1151561340157600080fd5b5050506040518051906020018051919650909450505b8385116134c657600160a060020a038a16600090815260106020908152604080832088845290915290205461344f908b908790613f05565b600160a060020a038b166000908152601060209081526040808320898452909152902054930192613483908b908790613f8a565b600160a060020a038a1660009081526010602090815260408083208984529091529020549101906134b7908a90879061400f565b60019095019490910190613417565b9199909850909650945050505050565b600160a060020a0381166000908152600c602052604081205481901180156135165750600160a060020a0382166000908152600c60205260409020544290105b1561354757600160a060020a0382166000908152600c6020526040902054420361353f83610d41565b029050610d35565b506000919050565b60008061355b84610d41565b915061356782846145ff565b90508015156135bc57600160a060020a0384166000818152600b60209081526040808320600580548552908352818420805460ff19166001179055938352600a825280832093548352929052908120556135e5565b600160a060020a0384166000908152600a60209081526040808320600554845290915290208190555b5050600554600160a060020a039092166000908152600d602052604090209190915560018054919091039055565b6025546000908190600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561365657600080fd5b5af1151561366357600080fd5b5050506040518051906020018051919350909150505b80821161381d5782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156136c657600080fd5b5af115156136d357600080fd5b5050506040518051602554909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561372657600080fd5b5af1151561373357600080fd5b5050506040518051905014151561374957600080fd5b82600160a060020a031663c46e3e858360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561378f57600080fd5b5af1151561379c57600080fd5b5050506040518051602554909150600160a060020a031663c46e3e858460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156137ef57600080fd5b5af115156137fc57600080fd5b5050506040518051905014151561381257600080fd5b600190910190613679565b602554600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561385b57600080fd5b5af1151561386857600080fd5b5050506040518051906020018051919350909150505b808211613bb45782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156138cb57600080fd5b5af115156138d857600080fd5b5050506040518051602554909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561392b57600080fd5b5af1151561393857600080fd5b5050506040518051905014151561394e57600080fd5b82600160a060020a03166369632f568360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561399457600080fd5b5af115156139a157600080fd5b5050506040518051602554909150600160a060020a03166369632f568460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156139f457600080fd5b5af11515613a0157600080fd5b50505060405180519050141515613a1757600080fd5b82600160a060020a03166321446cfe8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613a5d57600080fd5b5af11515613a6a57600080fd5b5050506040518051602554909150600160a060020a03166321446cfe8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613abd57600080fd5b5af11515613aca57600080fd5b50505060405180519050141515613ae057600080fd5b82600160a060020a0316636101a1f78360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613b2657600080fd5b5af11515613b3357600080fd5b5050506040518051602554909150600160a060020a0316636101a1f78460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613b8657600080fd5b5af11515613b9357600080fd5b50505060405180519050141515613ba957600080fd5b60019091019061387e565b505050565b600080600080600080600080600080600080602560009054906101000a9004600160a060020a0316600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515613c1c57600080fd5b5af11515613c2957600080fd5b5050506040518051906020018051919d50909b50505b8a8c11613d7b57602554600160a060020a03166328a42e9d8d60405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b1515613c8e57600080fd5b5af11515613c9b57600080fd5b5050506040518051906020018051906020018051906020018051906020018051929e50909c50909a50919550935050600160a060020a038d166328a42e9d8d60405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b1515613d1057600080fd5b5af11515613d1d57600080fd5b5050506040518051906020018051906020018051906020018051906020018051929b50909950909750919350915050838214613d5857600080fd5b888614613d6457600080fd5b878514613d7057600080fd5b6001909b019a613c3f565b602554600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515613db957600080fd5b5af11515613dc657600080fd5b5050506040518051906020018051919d50909b50505b8a8c11613ef657602554600160a060020a031663275babee8d60405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b1515613e2b57600080fd5b5af11515613e3857600080fd5b5050506040518051906020018051906020018051929c50909a5090985050600160a060020a038d1663275babee8d60405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b1515613e9c57600080fd5b5af11515613ea957600080fd5b505050604051805190602001805190602001805192995090975090955050898714613ed357600080fd5b888614613edf57600080fd5b878514613eeb57600080fd5b6001909b019a613ddc565b50505050505050505050505050565b600160a060020a03808416600081815260176020908152604080832087845282528083205493835260168252808320878452909152808220546025549294600a9485019391929116906369632f569088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600160a060020a038084166000818152601b60209081526040808320878452825280832054938352601a8252808320878452909152808220546025549294600a948501939192911690636101a1f79088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600160a060020a03808416600081815260196020908152604080832087845282528083205493835260188252808320878452909152808220546025549294600a9485019391929116906321446cfe9088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600083151561410757600160a060020a038516600081815260146020908152604080832087845282528083208054870190558383526015825280832087845282528083205493835260108252808320878452909152902054600a918201908402025b049050614102816131f0565b614326565b83600114156141e057600160a060020a038086166000818152601560209081526040808320888452825280832080548801905592825260148152828220878352905281902054602554600a93919291169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561419457600080fd5b5af115156141a157600080fd5b5050506040518051600160a060020a03891660009081526010602090815260408083208a8452909152902054860292019190910290508115156140f657fe5b836002141561421757600160a060020a03851660009081526016602090815260408083208684529091529020805483019055614326565b836003141561424e57600160a060020a03851660009081526017602090815260408083208684529091529020805483019055614326565b836004141561428557600160a060020a03851660009081526018602090815260408083208684529091529020805483019055614326565b83600514156142bc57600160a060020a03851660009081526019602090815260408083208684529091529020805483019055614326565b83600614156142f357600160a060020a0385166000908152601a602090815260408083208684529091529020805483019055614326565b836007141561432657600160a060020a0385166000908152601b6020908152604080832086845290915290208054830190555b5050505050565b600083151561439d57600160a060020a03851660008181526014602090815260408083208784528252808320805487900390558383526015825280832087845282528083205493835260108252808320878452909152902054600a918201908402025b049050614102858261354f565b836001141561447757600160a060020a03808616600081815260156020908152604080832088845282528083208054889003905592825260148152828220878352905281902054602554600a93919291169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561442b57600080fd5b5af1151561443857600080fd5b5050506040518051600160a060020a03891660009081526010602090815260408083208a84529091529020548602920191909102905081151561439057fe5b83600214156144af57600160a060020a0385166000908152601660209081526040808320868452909152902080548390039055614326565b83600314156144e757600160a060020a0385166000908152601760209081526040808320868452909152902080548390039055614326565b836004141561451f57600160a060020a0385166000908152601860209081526040808320868452909152902080548390039055614326565b836005141561455757600160a060020a0385166000908152601960209081526040808320868452909152902080548390039055614326565b836006141561458f57600160a060020a0385166000908152601a60209081526040808320868452909152902080548390039055614326565b836007141561432657600160a060020a0385166000908152601b602090815260408083208684529091529020805483900390555050505050565b6000808315156145dc57600091506145f8565b508282028284828115156145ec57fe5b04146145f457fe5b8091505b5092915050565b60008282111561460b57fe5b50900390565b60206040519081016040526000815290565b815481835581811511613bb457600083815260209020613bb4918101908301614673565b815481835581811511613bb457600202816002028360005260206000209182019101613bb49190614691565b610d3e91905b8082111561468d5760008155600101614679565b5090565b610d3e91905b8082111561468d57600080825560018201556002016146975600a165627a7a72305820ae34a2e0cd26a642ebf0feb477e2acbd6179b8a4cc4ee64d8b8a0c232cd8af480029

Swarm Source

bzzr://ae34a2e0cd26a642ebf0feb477e2acbd6179b8a4cc4ee64d8b8a0c232cd8af48

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.