ERC-20
Source Code
Overview
Max Total Supply
581,004,136,790,738,394 Goo
Holders
5,317
Market
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Balance
457,368,656,184 GooValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
| # | Exchange | Pair | Price | 24H Volume | % Volume |
|---|
Contract Name:
Goo
Compiler Version
v0.4.21+commit.dfe3193c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2018-04-13
*/
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 researchDivPercent = 8;
uint256 public gooDepositDivPercent = 2;
uint256 public totalEtherGooResearchPool; // Eth dividends to be split between players' goo production
uint256[] private totalGooProductionSnapshots; // The total goo production for each prior day past
uint256[] private totalGooDepositSnapshots; // The total goo deposited for each prior day past
uint256[] private allocatedGooResearchSnapshots; // Div pot #1 (research eth allocated to each prior day past)
uint256[] private allocatedGooDepositSnapshots; // Div pot #2 (deposit eth allocated to each prior day past)
uint256 public nextSnapshotTime;
// 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 => uint256)) private gooDepositSnapshots; // Store player's goo deposited 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 lastGooDepositFundClaim; // 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(address => mapping(uint256 => uint256)) private unitMaxCap;
// 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 raffleId;
}
// Allows us to query winner without looping (avoiding potential for gas limit)
struct TicketPurchase {
uint256 startId;
uint256 endId;
}
// Raffle tickets
mapping(address => TicketPurchases) private rareItemTicketsBoughtByPlayer;
mapping(uint256 => address[]) private itemRafflePlayers;
// Duplicating for the two raffles is not ideal
mapping(address => TicketPurchases) private rareUnitTicketsBoughtByPlayer;
mapping(uint256 => address[]) private unitRafflePlayers;
// Item raffle info
uint256 private constant RAFFLE_TICKET_BASE_GOO_PRICE = 1000;
uint256 private itemRaffleEndTime;
uint256 private itemRaffleRareId;
uint256 private itemRaffleTicketsBought;
address private itemRaffleWinner; // Address of winner
bool private itemRaffleWinningTicketSelected;
uint256 private itemRaffleTicketThatWon;
// Unit raffle info
uint256 private unitRaffleEndTime;
uint256 private unitRaffleId; // Raffle Id
uint256 private unitRaffleRareId; // Unit Id
uint256 private unitRaffleTicketsBought;
address private unitRaffleWinner; // Address of winner
bool private unitRaffleWinningTicketSelected;
uint256 private unitRaffleTicketThatWon;
// 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);
event ReferalGain(address player, address referal, uint256 amount);
event UpgradeMigration(address player, uint256 upgradeId, uint256 txProof);
GooGameConfig schema = GooGameConfig(0xf925a82b8c26520170c8d51b65a7def6364877b3);
// Constructor
function Goo() public payable {
owner = msg.sender;
}
function() payable {
// Fallback will donate to pot
totalEtherGooResearchPool += msg.value;
}
function beginGame(uint256 firstDivsTime) external payable {
require(msg.sender == owner);
require(!gameStarted);
gameStarted = true; // GO-OOOO!
nextSnapshotTime = firstDivsTime;
totalGooDepositSnapshots.push(0); // Add initial-zero snapshot
totalEtherGooResearchPool = msg.value; // Seed pot
}
// Incase community prefers goo deposit payments over production %, can be tweaked for balance
function tweakDailyDividends(uint256 newResearchPercent, uint256 newGooDepositPercent) external {
require(msg.sender == owner);
require(newResearchPercent > 0 && newResearchPercent <= 10);
require(newGooDepositPercent > 0 && newGooDepositPercent <= 10);
researchDivPercent = newResearchPercent;
gooDepositDivPercent = newGooDepositPercent;
}
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) {
uint256 lastSave = lastGooSaveTime[player];
if (lastSave > 0 && lastSave < block.timestamp) {
return (getGooProduction(player) * (block.timestamp - lastSave)) / 100;
}
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[player]);
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;
require(gooBalance[player] >= gooDecrease);
roughSupply -= gooDecrease;
gooBalance[player] -= gooDecrease;
} else {
uint256 gooGain = unclaimedGoo - purchaseCost;
roughSupply += gooGain;
gooBalance[player] += gooGain;
}
lastGooSaveTime[player] = block.timestamp;
}
function increasePlayersGooProduction(address player, uint256 increase) internal {
gooProductionSnapshots[player][allocatedGooResearchSnapshots.length] = getGooProduction(player) + increase;
lastGooProductionUpdate[player] = 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 {
uint256 schemaUnitId;
uint256 gooProduction;
uint256 gooCost;
uint256 ethCost;
uint256 existing = unitsOwned[msg.sender][unitId];
(schemaUnitId, gooProduction, gooCost, ethCost) = schema.getUnitInfo(unitId, existing, amount);
require(gameStarted);
require(schemaUnitId > 0); // Valid unit
require(ethCost == 0); // Free unit
uint256 newTotal = SafeMath.add(existing, amount);
if (newTotal > 99) { // Default unit limit
require(newTotal <= unitMaxCap[msg.sender][unitId]); // Housing upgrades (allow more units)
}
// Update players goo
updatePlayersGooFromPurchase(msg.sender, gooCost);
if (gooProduction > 0) {
increasePlayersGooProduction(msg.sender, getUnitsProduction(msg.sender, unitId, amount));
}
unitsOwned[msg.sender][unitId] = newTotal;
emit UnitBought(msg.sender, unitId, amount);
}
function buyEthUnit(uint256 unitId, uint256 amount) external payable {
uint256 schemaUnitId;
uint256 gooProduction;
uint256 gooCost;
uint256 ethCost;
uint256 existing = unitsOwned[msg.sender][unitId];
(schemaUnitId, gooProduction, gooCost, ethCost) = schema.getUnitInfo(unitId, existing, amount);
require(gameStarted);
require(schemaUnitId > 0);
require(ethBalance[msg.sender] + msg.value >= ethCost);
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;
uint256 newTotal = SafeMath.add(existing, amount);
if (newTotal > 99) { // Default unit limit
require(newTotal <= unitMaxCap[msg.sender][unitId]); // Housing upgrades (allow more units)
}
// Update players goo
updatePlayersGooFromPurchase(msg.sender, gooCost);
if (gooProduction > 0) {
increasePlayersGooProduction(msg.sender, getUnitsProduction(msg.sender, unitId, amount));
}
unitsOwned[msg.sender][unitId] += amount;
emit UnitBought(msg.sender, unitId, amount);
}
function sellUnit(uint256 unitId, uint256 amount) external {
uint256 existing = unitsOwned[msg.sender][unitId];
require(existing >= amount && amount > 0);
existing -= amount;
unitsOwned[msg.sender][unitId] = existing;
uint256 schemaUnitId;
uint256 gooProduction;
uint256 gooCost;
uint256 ethCost;
(schemaUnitId, gooProduction, gooCost, ethCost) = schema.getUnitInfo(unitId, existing, amount);
require(schema.unitSellable(unitId));
uint256 gooChange = balanceOfUnclaimedGoo(msg.sender) + ((gooCost * 3) / 4); // Claim unsaved goo whilst here
lastGooSaveTime[msg.sender] = block.timestamp;
roughSupply += gooChange;
gooBalance[msg.sender] += gooChange;
if (gooProduction > 0) {
reducePlayersGooProduction(msg.sender, getUnitsProduction(msg.sender, unitId, amount));
}
if (ethCost > 0) { // Premium units sell for 75% of buy cost
ethBalance[msg.sender] += (ethCost * 3) / 4;
}
emit UnitSold(msg.sender, unitId, amount);
}
function buyUpgrade(uint256 upgradeId) external payable {
uint256 gooCost;
uint256 ethCost;
uint256 upgradeClass;
uint256 unitId;
uint256 upgradeValue;
uint256 prerequisiteUpgrade;
(gooCost, ethCost, upgradeClass, unitId, upgradeValue, prerequisiteUpgrade) = schema.getUpgradeInfo(upgradeId);
require(gameStarted);
require(unitId > 0); // Valid upgrade
require(!upgradesOwned[msg.sender][upgradeId]); // Haven't already purchased
if (prerequisiteUpgrade > 0) {
require(upgradesOwned[msg.sender][prerequisiteUpgrade]);
}
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]);
increasePlayersGooProduction(player, productionGain);
} else if (upgradeClass == 1) {
unitGooProductionMultiplier[player][unitId] += upgradeValue;
productionGain = unitsOwned[player][unitId] * upgradeValue * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId]);
increasePlayersGooProduction(player, 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;
} else if (upgradeClass == 8) {
unitMaxCap[player][unitId] = upgradeValue; // Housing upgrade (new capacity)
}
}
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]);
reducePlayersGooProduction(player, productionLoss);
} else if (upgradeClass == 1) {
unitGooProductionMultiplier[player][unitId] -= upgradeValue;
productionLoss = unitsOwned[player][unitId] * upgradeValue * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId]);
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 {
uint256 upgradeClass;
uint256 unitId;
uint256 upgradeValue;
(upgradeClass, unitId, upgradeValue) = schema.getRareInfo(rareId);
address previousOwner = rareItemOwner[rareId];
require(previousOwner != 0);
require(unitId > 0);
// We have to claim buyer's goo before updating their production values
updatePlayersGoo(msg.sender);
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);
uint256 ethCost = rareItemPrice[rareId];
require(ethBalance[msg.sender] + msg.value >= ethCost);
// 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 fundGooResearch(uint256 amount) external {
updatePlayersGooFromPurchase(msg.sender, amount);
gooDepositSnapshots[msg.sender][totalGooDepositSnapshots.length - 1] += amount;
totalGooDepositSnapshots[totalGooDepositSnapshots.length - 1] += 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][endSnapShot] && 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;
emit ReferalGain(referer, msg.sender, referalDivs);
}
ethBalance[msg.sender] += researchShare - referalDivs;
}
function claimGooDepositDividends(address referer, uint256 startSnapshot, uint256 endSnapShot) external {
require(startSnapshot <= endSnapShot);
require(startSnapshot >= lastGooDepositFundClaim[msg.sender]);
require(endSnapShot < allocatedGooDepositSnapshots.length);
uint256 depositShare;
for (uint256 i = startSnapshot; i <= endSnapShot; i++) {
depositShare += (allocatedGooDepositSnapshots[i] * gooDepositSnapshots[msg.sender][i]) / totalGooDepositSnapshots[i];
}
lastGooDepositFundClaim[msg.sender] = endSnapShot + 1;
uint256 referalDivs;
if (referer != address(0) && referer != msg.sender) {
referalDivs = depositShare / 100; // 1%
ethBalance[referer] += referalDivs;
emit ReferalGain(referer, msg.sender, referalDivs);
}
ethBalance[msg.sender] += depositShare - referalDivs;
}
// Allocate pot #1 divs for the day (00:00 cron job)
function snapshotDailyGooResearchFunding() external {
require(msg.sender == owner);
uint256 todaysGooResearchFund = (totalEtherGooResearchPool * researchDivPercent) / 100; // 8% of pool daily
totalEtherGooResearchPool -= todaysGooResearchFund;
totalGooProductionSnapshots.push(totalGooProduction);
allocatedGooResearchSnapshots.push(todaysGooResearchFund);
nextSnapshotTime = block.timestamp + 24 hours;
}
// Allocate pot #2 divs for the day (12:00 cron job)
function snapshotDailyGooDepositFunding() external {
require(msg.sender == owner);
uint256 todaysGooDepositFund = (totalEtherGooResearchPool * gooDepositDivPercent) / 100; // 2% of pool daily
totalEtherGooResearchPool -= todaysGooDepositFund;
totalGooDepositSnapshots.push(0); // Reset for to store next day's deposits
allocatedGooDepositSnapshots.push(todaysGooDepositFund); // Store to payout divs for previous day deposits
}
// Raffle for rare items
function buyItemRaffleTicket(uint256 amount) external {
require(itemRaffleEndTime >= 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 = rareItemTicketsBoughtByPlayer[msg.sender];
// If we need to reset tickets from a previous raffle
if (purchases.raffleId != itemRaffleRareId) {
purchases.numPurchases = 0;
purchases.raffleId = itemRaffleRareId;
itemRafflePlayers[itemRaffleRareId].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(itemRaffleTicketsBought, itemRaffleTicketsBought + (amount - 1)); // (eg: buy 10, get id's 0-9)
// Finally update ticket total
itemRaffleTicketsBought += amount;
}
// Raffle for rare units
function buyUnitRaffleTicket(uint256 amount) external {
require(unitRaffleEndTime >= 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 = rareUnitTicketsBoughtByPlayer[msg.sender];
// If we need to reset tickets from a previous raffle
if (purchases.raffleId != unitRaffleId) {
purchases.numPurchases = 0;
purchases.raffleId = unitRaffleId;
unitRafflePlayers[unitRaffleId].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(unitRaffleTicketsBought, unitRaffleTicketsBought + (amount - 1)); // (eg: buy 10, get id's 0-9)
// Finally update ticket total
unitRaffleTicketsBought += amount;
}
function startItemRaffle(uint256 endTime, uint256 rareId) external {
require(msg.sender == owner);
require(schema.validRareId(rareId));
require(rareItemOwner[rareId] == 0);
require(block.timestamp < endTime);
if (itemRaffleRareId != 0) { // Sanity to assure raffle has ended before next one starts
require(itemRaffleWinner != 0);
}
// Reset previous raffle info
itemRaffleWinningTicketSelected = false;
itemRaffleTicketThatWon = 0;
itemRaffleWinner = 0;
itemRaffleTicketsBought = 0;
// Set current raffle info
itemRaffleEndTime = endTime;
itemRaffleRareId = rareId;
}
function startUnitRaffle(uint256 endTime, uint256 unitId) external {
require(msg.sender == owner);
require(block.timestamp < endTime);
if (unitRaffleRareId != 0) { // Sanity to assure raffle has ended before next one starts
require(unitRaffleWinner != 0);
}
// Reset previous raffle info
unitRaffleWinningTicketSelected = false;
unitRaffleTicketThatWon = 0;
unitRaffleWinner = 0;
unitRaffleTicketsBought = 0;
// Set current raffle info
unitRaffleEndTime = endTime;
unitRaffleRareId = unitId;
unitRaffleId++; // Can't use unitRaffleRareId (as rare units are not unique)
}
function awardItemRafflePrize(address checkWinner, uint256 checkIndex) external {
require(itemRaffleEndTime < block.timestamp);
require(itemRaffleWinner == 0);
require(rareItemOwner[itemRaffleRareId] == 0);
if (!itemRaffleWinningTicketSelected) {
drawRandomItemWinner(); // 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 = rareItemTicketsBoughtByPlayer[checkWinner];
if (tickets.numPurchases > 0 && checkIndex < tickets.numPurchases && tickets.raffleId == itemRaffleRareId) {
TicketPurchase storage checkTicket = tickets.ticketsBought[checkIndex];
if (itemRaffleTicketThatWon >= checkTicket.startId && itemRaffleTicketThatWon <= checkTicket.endId) {
assignItemRafflePrize(checkWinner); // WINNER!
return;
}
}
}
// Otherwise just naively try to find the winner (will work until mass amounts of players)
for (uint256 i = 0; i < itemRafflePlayers[itemRaffleRareId].length; i++) {
address player = itemRafflePlayers[itemRaffleRareId][i];
TicketPurchases storage playersTickets = rareItemTicketsBoughtByPlayer[player];
uint256 endIndex = playersTickets.numPurchases - 1;
// Minor optimization to avoid checking every single player
if (itemRaffleTicketThatWon >= playersTickets.ticketsBought[0].startId && itemRaffleTicketThatWon <= playersTickets.ticketsBought[endIndex].endId) {
for (uint256 j = 0; j < playersTickets.numPurchases; j++) {
TicketPurchase storage playerTicket = playersTickets.ticketsBought[j];
if (itemRaffleTicketThatWon >= playerTicket.startId && itemRaffleTicketThatWon <= playerTicket.endId) {
assignItemRafflePrize(player); // WINNER!
return;
}
}
}
}
}
function awardUnitRafflePrize(address checkWinner, uint256 checkIndex) external {
require(unitRaffleEndTime < block.timestamp);
require(unitRaffleWinner == 0);
if (!unitRaffleWinningTicketSelected) {
drawRandomUnitWinner(); // 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 = rareUnitTicketsBoughtByPlayer[checkWinner];
if (tickets.numPurchases > 0 && checkIndex < tickets.numPurchases && tickets.raffleId == unitRaffleId) {
TicketPurchase storage checkTicket = tickets.ticketsBought[checkIndex];
if (unitRaffleTicketThatWon >= checkTicket.startId && unitRaffleTicketThatWon <= checkTicket.endId) {
assignUnitRafflePrize(checkWinner); // WINNER!
return;
}
}
}
// Otherwise just naively try to find the winner (will work until mass amounts of players)
for (uint256 i = 0; i < unitRafflePlayers[unitRaffleId].length; i++) {
address player = unitRafflePlayers[unitRaffleId][i];
TicketPurchases storage playersTickets = rareUnitTicketsBoughtByPlayer[player];
uint256 endIndex = playersTickets.numPurchases - 1;
// Minor optimization to avoid checking every single player
if (unitRaffleTicketThatWon >= playersTickets.ticketsBought[0].startId && unitRaffleTicketThatWon <= playersTickets.ticketsBought[endIndex].endId) {
for (uint256 j = 0; j < playersTickets.numPurchases; j++) {
TicketPurchase storage playerTicket = playersTickets.ticketsBought[j];
if (unitRaffleTicketThatWon >= playerTicket.startId && unitRaffleTicketThatWon <= playerTicket.endId) {
assignUnitRafflePrize(player); // WINNER!
return;
}
}
}
}
}
function assignItemRafflePrize(address winner) internal {
itemRaffleWinner = winner;
rareItemOwner[itemRaffleRareId] = winner;
rareItemPrice[itemRaffleRareId] = (schema.rareStartPrice(itemRaffleRareId) * 21) / 20; // Buy price slightly higher (Div pool cut)
updatePlayersGoo(winner);
uint256 upgradeClass;
uint256 unitId;
uint256 upgradeValue;
(upgradeClass, unitId, upgradeValue) = schema.getRareInfo(itemRaffleRareId);
upgradeUnitMultipliers(winner, upgradeClass, unitId, upgradeValue);
}
function assignUnitRafflePrize(address winner) internal {
unitRaffleWinner = winner;
updatePlayersGoo(winner);
increasePlayersGooProduction(winner, getUnitsProduction(winner, unitRaffleRareId, 1));
unitsOwned[winner][unitRaffleRareId] += 1;
}
// Random enough for small contests (Owner only to prevent trial & error execution)
function drawRandomItemWinner() public {
require(msg.sender == owner);
require(itemRaffleEndTime < block.timestamp);
require(!itemRaffleWinningTicketSelected);
uint256 seed = itemRaffleTicketsBought + block.timestamp;
itemRaffleTicketThatWon = addmod(uint256(block.blockhash(block.number-1)), seed, itemRaffleTicketsBought);
itemRaffleWinningTicketSelected = true;
}
function drawRandomUnitWinner() public {
require(msg.sender == owner);
require(unitRaffleEndTime < block.timestamp);
require(!unitRaffleWinningTicketSelected);
uint256 seed = unitRaffleTicketsBought + block.timestamp;
unitRaffleTicketThatWon = addmod(uint256(block.blockhash(block.number-1)), seed, unitRaffleTicketsBought);
unitRaffleWinningTicketSelected = true;
}
// Gives players the upgrades they 'previously paid for' (i.e. will be one of same unit/type/value of their v1 purchase)
// Tx of their (prior) purchase is provided so can be validated by anyone for 0 abuse
function migrateV1Upgrades(address[] playerToCredit, uint256[] upgradeIds, uint256[] txProof) external {
require(msg.sender == owner);
require(!gameStarted); // Pre-game migration
for (uint256 i = 0; i < txProof.length; i++) {
address player = playerToCredit[i];
uint256 upgradeId = upgradeIds[i];
uint256 unitId = schema.upgradeUnitId(upgradeId);
if (unitId > 0 && !upgradesOwned[player][upgradeId]) { // Upgrade valid (and haven't already migrated)
uint256 upgradeClass = schema.upgradeClass(upgradeId);
uint256 upgradeValue = schema.upgradeValue(upgradeId);
upgradeUnitMultipliers(player, upgradeClass, unitId, upgradeValue);
upgradesOwned[player][upgradeId] = true;
emit UpgradeMigration(player, upgradeId, txProof[i]);
}
}
}
function protectAddress(address exchange, bool shouldProtect) external {
require(msg.sender == owner);
if (shouldProtect) {
require(getGooProduction(exchange) == 0); // Can't protect actual players
}
protectedAddresses[exchange] = shouldProtect;
}
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;
roughSupply -= gooDecrease;
} else {
uint256 gooGain = unclaimedGoo - stealingPower;
gooBalance[target] += gooGain;
roughSupply += 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) {
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++;
}
if (battleCooldown[player] > block.timestamp) { // When on battle cooldown you're vulnerable (starting value is 50% normal power)
defendingPower = schema.getWeakenedDefensePower(defendingPower);
}
return (attackingPower, defendingPower, stealingPower, battleCooldown[player]);
}
function getUnitsProduction(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
return (amount * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId]) * (10 + unitGooProductionMultiplier[player][unitId]));
}
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, 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, totalGooDepositSnapshots[totalGooDepositSnapshots.length - 1], gooDepositSnapshots[msg.sender][totalGooDepositSnapshots.length - 1],
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 display on website
function viewUnclaimedDepositDividends() external constant returns (uint256, uint256, uint256) {
uint256 startSnapshot = lastGooDepositFundClaim[msg.sender];
uint256 latestSnapshot = allocatedGooDepositSnapshots.length - 1; // No snapshots to begin with
uint256 depositShare;
for (uint256 i = startSnapshot; i <= latestSnapshot; i++) {
depositShare += (allocatedGooDepositSnapshots[i] * gooDepositSnapshots[msg.sender][i]) / totalGooDepositSnapshots[i];
}
return (depositShare, startSnapshot, latestSnapshot);
}
// To allow clients to verify contestants
function getItemRafflePlayers(uint256 raffleId) external constant returns (address[]) {
return (itemRafflePlayers[raffleId]);
}
// To allow clients to verify contestants
function getUnitRafflePlayers(uint256 raffleId) external constant returns (address[]) {
return (unitRafflePlayers[raffleId]);
}
// To allow clients to verify contestants
function getPlayersItemTickets(address player) external constant returns (uint256[], uint256[]) {
TicketPurchases storage playersTickets = rareItemTicketsBoughtByPlayer[player];
if (playersTickets.raffleId == itemRaffleRareId) {
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 allow clients to verify contestants
function getPlayersUnitTickets(address player) external constant returns (uint256[], uint256[]) {
TicketPurchases storage playersTickets = rareUnitTicketsBoughtByPlayer[player];
if (playersTickets.raffleId == unitRaffleId) {
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 getLatestItemRaffleInfo() external constant returns (uint256, uint256, uint256, address, uint256) {
return (itemRaffleEndTime, itemRaffleRareId, itemRaffleTicketsBought, itemRaffleWinner, itemRaffleTicketThatWon);
}
// To display on website
function getLatestUnitRaffleInfo() external constant returns (uint256, uint256, uint256, address, uint256) {
return (unitRaffleEndTime, unitRaffleRareId, unitRaffleTicketsBought, unitRaffleWinner, unitRaffleTicketThatWon);
}
// 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;
// Requires ALL upgrade stats match up or fail execution
(startId, endId) = schema.upgradeIdRange();
while (startId <= endId) {
require(schema.upgradeGooCost(startId) == newSchema.upgradeGooCost(startId));
require(schema.upgradeEthCost(startId) == newSchema.upgradeEthCost(startId));
require(schema.upgradeClass(startId) == newSchema.upgradeClass(startId));
require(schema.upgradeUnitId(startId) == newSchema.upgradeUnitId(startId));
require(schema.upgradeValue(startId) == newSchema.upgradeValue(startId));
startId++;
}
// Requires ALL rare stats match up or fail execution
(startId, endId) = schema.rareIdRange();
while (startId <= endId) {
uint256 oldClass;
uint256 oldUnitId;
uint256 oldValue;
uint256 newClass;
uint256 newUnitId;
uint256 newValue;
(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 = 15;
uint256 public constant currentNumberOfUpgrades = 210;
uint256 public constant currentNumberOfRares = 2;
address public owner;
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;
bool unitSellable; // Rare units (from raffle) not sellable
}
struct Upgrade {
uint256 upgradeId;
uint256 gooCost;
uint256 ethCost;
uint256 upgradeClass;
uint256 unitId;
uint256 upgradeValue;
uint256 prerequisiteUpgrade;
}
struct Rare {
uint256 rareId;
uint256 ethCost;
uint256 rareClass;
uint256 unitId;
uint256 rareValue;
}
function GooGameConfig() public {
owner = msg.sender;
rareInfo[1] = Rare(1, 0.5 ether, 1, 1, 40); // 40 = +400%
rareInfo[2] = Rare(2, 0.5 ether, 0, 2, 35); // +35
unitInfo[1] = Unit(1, 0, 10, 0, 2, 0, 0, 0, true);
unitInfo[2] = Unit(2, 100, 50, 0, 5, 0, 0, 0, true);
unitInfo[3] = Unit(3, 0, 0, 0.01 ether, 100, 0, 0, 0, true);
unitInfo[4] = Unit(4, 200, 100, 0, 10, 0, 0, 0, true);
unitInfo[5] = Unit(5, 500, 250, 0, 20, 0, 0, 0, true);
unitInfo[6] = Unit(6, 1000, 500, 0, 40, 0, 0, 0, true);
unitInfo[7] = Unit(7, 0, 1000, 0.05 ether, 500, 0, 0, 0, true);
unitInfo[8] = Unit(8, 1500, 750, 0, 60, 0, 0, 0, true);
unitInfo[9] = Unit(9, 0, 0, 10 ether, 6000, 0, 0, 0, false); // First secret rare unit from raffle (unsellable)
unitInfo[40] = Unit(40, 50, 25, 0, 0, 10, 10, 10000, true);
unitInfo[41] = Unit(41, 100, 50, 0, 0, 1, 25, 500, true);
unitInfo[42] = Unit(42, 0, 0, 0.01 ether, 0, 200, 10, 50000, true);
unitInfo[43] = Unit(43, 250, 125, 0, 0, 25, 1, 15000, true);
unitInfo[44] = Unit(44, 500, 250, 0, 0, 20, 40, 5000, true);
unitInfo[45] = Unit(45, 0, 2500, 0.02 ether, 0, 0, 0, 100000, true);
}
address allowedConfig;
function setConfigSetupContract(address schema) external {
require(msg.sender == owner);
allowedConfig = schema;
}
function addUpgrade(uint256 id, uint256 goo, uint256 eth, uint256 class, uint256 unit, uint256 value, uint256 prereq) external {
require(msg.sender == allowedConfig);
upgradeInfo[id] = Upgrade(id, goo, eth, class, unit, value, prereq);
}
function getGooCostForUnit(uint256 unitId, uint256 existing, uint256 amount) public constant returns (uint256) {
Unit storage unit = unitInfo[unitId];
if (amount == 1) { // 1
if (existing == 0) {
return unit.baseGooCost;
} else {
return unit.baseGooCost + (existing * unit.gooCostIncreaseHalf * 2);
}
} else if (amount > 1) {
uint256 existingCost;
if (existing > 0) { // Gated by unit limit
existingCost = (unit.baseGooCost * existing) + (existing * (existing - 1) * unit.gooCostIncreaseHalf);
}
existing = SafeMath.add(existing, amount);
return SafeMath.add(SafeMath.mul(unit.baseGooCost, existing), SafeMath.mul(SafeMath.mul(existing, (existing - 1)), unit.gooCostIncreaseHalf)) - existingCost;
}
}
function getWeakenedDefensePower(uint256 defendingPower) external constant returns (uint256) {
return defendingPower / 2;
}
function validRareId(uint256 rareId) external constant returns (bool) {
return (rareId > 0 && rareId < 3);
}
function unitSellable(uint256 unitId) external constant returns (bool) {
return unitInfo[unitId].unitSellable;
}
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 upgradeGooCost(uint256 upgradeId) external constant returns (uint256) {
return upgradeInfo[upgradeId].gooCost;
}
function upgradeEthCost(uint256 upgradeId) external constant returns (uint256) {
return upgradeInfo[upgradeId].ethCost;
}
function upgradeClass(uint256 upgradeId) external constant returns (uint256) {
return upgradeInfo[upgradeId].upgradeClass;
}
function upgradeUnitId(uint256 upgradeId) external constant returns (uint256) {
return upgradeInfo[upgradeId].unitId;
}
function upgradeValue(uint256 upgradeId) external constant returns (uint256) {
return upgradeInfo[upgradeId].upgradeValue;
}
function productionUnitIdRange() external constant returns (uint256, uint256) {
return (1, 9);
}
function battleUnitIdRange() external constant returns (uint256, uint256) {
return (40, 45);
}
function upgradeIdRange() external constant returns (uint256, uint256) {
return (1, 210);
}
function rareIdRange() external constant returns (uint256, uint256) {
return (1, 2);
}
function getUpgradeInfo(uint256 upgradeId) external constant returns (uint256, uint256, uint256, uint256, uint256, uint256) {
return (upgradeInfo[upgradeId].gooCost, upgradeInfo[upgradeId].ethCost, upgradeInfo[upgradeId].upgradeClass,
upgradeInfo[upgradeId].unitId, upgradeInfo[upgradeId].upgradeValue, upgradeInfo[upgradeId].prerequisiteUpgrade);
}
function getRareInfo(uint256 rareId) external constant returns (uint256, uint256, uint256) {
return (rareInfo[rareId].rareClass, rareInfo[rareId].unitId, rareInfo[rareId].rareValue);
}
function getUnitInfo(uint256 unitId, uint256 existing, uint256 amount) external constant returns (uint256, uint256, uint256, uint256) {
return (unitInfo[unitId].unitId, unitInfo[unitId].baseGooProduction, getGooCostForUnit(unitId, existing, amount), SafeMath.mul(unitInfo[unitId].ethCost, amount));
}
}
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
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getPlayersItemTickets","outputs":[{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"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":false,"inputs":[{"name":"playerToCredit","type":"address[]"},{"name":"upgradeIds","type":"uint256[]"},{"name":"txProof","type":"uint256[]"}],"name":"migrateV1Upgrades","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"viewUnclaimedDepositDividends","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"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":"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":false,"inputs":[{"name":"endTime","type":"uint256"},{"name":"unitId","type":"uint256"}],"name":"startUnitRaffle","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"drawRandomUnitWinner","outputs":[],"payable":false,"stateMutability":"nonpayable","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":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":false,"inputs":[],"name":"drawRandomItemWinner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gooDepositDivPercent","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":"newResearchPercent","type":"uint256"},{"name":"newGooDepositPercent","type":"uint256"}],"name":"tweakDailyDividends","outputs":[],"payable":false,"stateMutability":"nonpayable","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":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"buyUnitRaffleTicket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLatestItemRaffleInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getPlayersUnitTickets","outputs":[{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"raffleId","type":"uint256"}],"name":"getItemRafflePlayers","outputs":[{"name":"","type":"address[]"}],"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":"shouldProtect","type":"bool"}],"name":"protectAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"checkWinner","type":"address"},{"name":"checkIndex","type":"uint256"}],"name":"awardItemRafflePrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"endTime","type":"uint256"},{"name":"rareId","type":"uint256"}],"name":"startItemRaffle","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":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"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"referer","type":"address"},{"name":"startSnapshot","type":"uint256"},{"name":"endSnapShot","type":"uint256"}],"name":"claimGooDepositDividends","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"referer","type":"address"},{"name":"startSnapshot","type":"uint256"},{"name":"endSnapShot","type":"uint256"}],"name":"claimResearchDividends","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"checkWinner","type":"address"},{"name":"checkIndex","type":"uint256"}],"name":"awardUnitRafflePrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"researchDivPercent","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":"amount","type":"uint256"}],"name":"fundGooResearch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"upgradeId","type":"uint256"}],"name":"buyUpgrade","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getLatestUnitRaffleInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":"buyItemRaffleTicket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"snapshotDailyGooResearchFunding","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"raffleId","type":"uint256"}],"name":"getUnitRafflePlayers","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"buyEthUnit","outputs":[],"payable":true,"stateMutability":"payable","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"},{"constant":false,"inputs":[],"name":"snapshotDailyGooDepositFunding","outputs":[],"payable":false,"stateMutability":"nonpayable","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":false,"name":"player","type":"address"},{"indexed":false,"name":"referal","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ReferalGain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"player","type":"address"},{"indexed":false,"name":"upgradeId","type":"uint256"},{"indexed":false,"name":"txProof","type":"uint256"}],"name":"UpgradeMigration","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"}]Contract Creation Code
60606040526008600355600260048190556033805473f925a82b8c26520170c8d51b65a7def6364877b3600160a060020a031991821617909155815416600160a060020a033316179055615754806100586000396000f3006060604052600436106102795763ffffffff60e060020a60003504166302b68bbf811461028357806306fdde031461033b578063095ea7b3146103c55780630b407022146103fb57806313aa7b6f146104335780631746bd1b1461046a578063179fc99f1461055557806318160ddd1461058657806318d801681461059957806319e9e5de146105b257806322bfba59146105d157806323b872dd146105e457806325a7650a1461060c5780632bfd2e06146106175780633081fe3f14610630578063313ce5671461064f57806338198c65146106785780633bed33ce1461068b5780634a1d08af146106a15780634a617fba146106b45780634efdd4f9146106c757806353dd8881146106da5780635dc22cce146106f35780635e123ce41461071257806360f61a4c1461072557806364f54a171461073b5780636a7d1a7e146107885780636c20d755146107a757806370a082311461081057806370bc52fb1461082f57806370d9f7dc14610853578063716e560414610875578063751fef651461088e5780637c85a757146108a75780637ef58e73146108c657806380fa7902146108d95780638d4777c8146109235780638da5cb5b146109485780638fafb286146109775780639323eaad1461099c57806393d7c6bf146109be57806395d89b41146109d15780639e30dd5f146109e4578063a21f74b8146109ef578063a5a2cb1914610a05578063a7b7f1d414610a10578063a89cdad914610a23578063a9059cbb14610a36578063b1d6600314610a58578063b912950e14610a6b578063c38f074114610a81578063c9c286c614610a94578063d8737d8a14610aaa578063dd62ed3e14610ab8578063f2f921e614610add575b6005805434019055005b341561028e57600080fd5b6102a2600160a060020a0360043516610af0565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156102e65780820151838201526020016102ce565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561032557808201518382015260200161030d565b5050505090500194505050505060405180910390f35b341561034657600080fd5b61034e610c16565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561038a578082015183820152602001610372565b50505050905090810190601f1680156103b75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103d057600080fd5b6103e7600160a060020a0360043516602435610c4d565b604051901515815260200160405180910390f35b341561040657600080fd5b6104316024600480358281019290820135918135808301929082013591604435918201910135610cb9565b005b341561043e57600080fd5b610446610f59565b60405180848152602001838152602001828152602001935050505060405180910390f35b341561047557600080fd5b61047d610ffe565b604051808c81526020018b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156104f75780820151838201526020016104df565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561053657808201518382015260200161051e565b505050509050019d505050505050505050505050505060405180910390f35b341561056057600080fd5b610574600160a060020a03600435166113e6565b60405190815260200160405180910390f35b341561059157600080fd5b610574611401565b34156105a457600080fd5b610431600435602435611408565b34156105bd57600080fd5b610574600160a060020a036004351661148e565b34156105dc57600080fd5b6104316114bb565b34156105ef57600080fd5b6103e7600160a060020a0360043581169060243516604435611542565b610431600435611634565b341561062257600080fd5b6104316004356024356116b4565b341561063b57600080fd5b610574600160a060020a0360043516611894565b341561065a57600080fd5b6106626118a6565b60405160ff909116815260200160405180910390f35b341561068357600080fd5b6105746118ab565b341561069657600080fd5b6104316004356118b1565b34156106ac57600080fd5b610431611921565b34156106bf57600080fd5b6105746119a8565b34156106d257600080fd5b6104466119ae565b34156106e557600080fd5b610431600435602435611ab0565b34156106fe57600080fd5b610431600160a060020a0360043516611b0e565b341561071d57600080fd5b6103e7611e84565b341561073057600080fd5b610431600435611e94565b341561074657600080fd5b61074e611fec565b6040519485526020850193909352604080850192909252600160a060020a03166060840152608083019190915260a0909101905180910390f35b341561079357600080fd5b6102a2600160a060020a036004351661200c565b34156107b257600080fd5b6107bd600435612126565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107fc5780820151838201526020016107e4565b505050509050019250505060405180910390f35b341561081b57600080fd5b610574600160a060020a03600435166121a1565b341561083a57600080fd5b610431600160a060020a036004351660243515156121cd565b341561085e57600080fd5b610431600160a060020a036004351660243561222c565b341561088057600080fd5b610431600435602435612480565b341561089957600080fd5b610431600435602435612588565b34156108b257600080fd5b610431600160a060020a03600435166127e0565b34156108d157600080fd5b610574612842565b34156108e457600080fd5b6108f8600160a060020a0360043516612848565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b341561092e57600080fd5b610431600160a060020a0360043516602435604435612a26565b341561095357600080fd5b61095b612bcd565b604051600160a060020a03909116815260200160405180910390f35b341561098257600080fd5b610431600160a060020a0360043516602435604435612bdc565b34156109a757600080fd5b610431600160a060020a0360043516602435612e85565b34156109c957600080fd5b6105746130a3565b34156109dc57600080fd5b61034e6130a9565b6104316004356130e0565b34156109fa57600080fd5b6104316004356132e3565b610431600435613344565b3415610a1b57600080fd5b61074e61354e565b3415610a2e57600080fd5b61057461356e565b3415610a4157600080fd5b6103e7600160a060020a0360043516602435613574565b3415610a6357600080fd5b6102a2613612565b3415610a7657600080fd5b610431600435613807565b3415610a8c57600080fd5b61043161395f565b3415610a9f57600080fd5b6107bd6004356139e9565b610431600435602435613a62565b3415610ac357600080fd5b610574600160a060020a0360043581169060243516613cca565b3415610ae857600080fd5b610431613cf5565b610af8615688565b610b00615688565b6000610b0a615688565b610b12615688565b600160a060020a038616600090815260246020526040812060295460028201549195501415610c0a578360010154604051805910610b4d5750595b908082528060200260200182016040525092508360010154604051805910610b725750595b90808252806020026020018201604052509150600090505b8360010154811015610c0a578354849082908110610ba457fe5b906000526020600020906002020160000154838281518110610bc257fe5b602090810290910101528354849082908110610bda57fe5b906000526020600020906002020160010154828281518110610bf857fe5b60209081029091010152600101610b8a565b50909590945092505050565b60408051908101604052600781527f49646c6545746800000000000000000000000000000000000000000000000000602082015281565b600160a060020a03338116600081815260226020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b6002546000908190819081908190819033600160a060020a03908116911614610ce157600080fd5b60025460a060020a900460ff1615610cf857600080fd5b600095505b86861015610f4b578b8b87818110610d1157fe5b90506020020135600160a060020a031694508989878181101515610d3157fe5b60335460209091029290920135955050600160a060020a03166372fecf848560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610d8657600080fd5b5af11515610d9357600080fd5b5050506040518051935050600083118015610dd25750600160a060020a038516600090815260166020908152604080832087845290915290205460ff16155b15610f4057603354600160a060020a031663309ba1208560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610e1f57600080fd5b5af11515610e2c57600080fd5b5050506040518051603354909350600160a060020a03169050630caeb3508560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610e8157600080fd5b5af11515610e8e57600080fd5b505050604051805190509050610ea685838584613d69565b600160a060020a03851660009081526016602090815260408083208784529091529020805460ff191660011790557fb84e528e18e54dd4bb87635427809661099f52b6fb31e5c969e6f07c9a19913c85858a8a8a818110610f0357fe5b905060200201356040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15b600190950194610cfd565b505050505050505050505050565b600160a060020a033316600090815260136020526040812054600954829182916000190182825b828111610ff3576007805482908110610f9557fe5b6000918252602080832090910154600160a060020a0333168352600e825260408084208585529092529120546009805484908110610fcf57fe5b90600052602060002090015402811515610fe557fe5b049190910190600101610f80565b509591945092509050565b6000806000806000806000806000611014615688565b61101c615688565b611024615688565b61102c615688565b60335460009081908190600160a060020a0316638975e45f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561107257600080fd5b5af1151561107f57600080fd5b505050604051805190506040518059106110965750595b9080825280602002602001820160405250603354909550600160a060020a031663f10a98486040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156110e957600080fd5b5af115156110f657600080fd5b5050506040518051905060405180591061110d5750595b9080825280602002602001820160405250603354909450600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561115f57600080fd5b5af1151561116c57600080fd5b5050506040518051906020018051919450909250505b8183116111cf57600160a060020a03331660009081526015602090815260408083208684529091529020548582815181106111b957fe5b6020908102909101015260019283019201611182565b603354600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561120d57600080fd5b5af1151561121a57600080fd5b5050506040518051906020018051919450909250505b81831161127d57600160a060020a033316600090815260156020908152604080832086845290915290205485828151811061126757fe5b6020908102909101015260019283019201611230565b50603354600090600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156112bf57600080fd5b5af115156112cc57600080fd5b5050506040518051906020018051919450909250505b81831161133757600160a060020a033316600090815260166020908152604080832086845290915290205460ff1684828151811061131c57fe5b911515602092830290910190910152600192830192016112e2565b600554600154600780544293929190600019810190811061135457fe5b6000918252602080832090910154600160a060020a03339081168452600e835260408085206007546000190186529093529190922054600a549091611398906121a1565b33600160a060020a0381166000908152600b6020526040902054906113bc9061148e565b8d8d9f509f509f509f509f509f509f509f509f509f509f505050505050909192939495969798999a565b600160a060020a03166000908152600b602052604090205490565b6000545b90565b60025433600160a060020a0390811691161461142357600080fd5b4282901061143057600080fd5b602f541561144f57603154600160a060020a0316151561144f57600080fd5b603180546000603281905574ffffffffffffffffffffffffffffffffffffffffff19909116909155603055602d91909155602f55602e80546001019055565b600160a060020a03166000908152600d602090815260408083206011835281842054845290915290205490565b60025460009033600160a060020a039081169116146114d957600080fd5b602d544290106114e857600080fd5b60315460a060020a900460ff16156114ff57600080fd5b506030544281019080151561151057fe5b8160001943014008603255506031805474ff0000000000000000000000000000000000000000191660a060020a179055565b600061154d84614030565b600160a060020a0380851660009081526022602090815260408083203390941683529290522054821180159061159b5750600160a060020a0384166000908152600c60205260409020548211155b15156115a657600080fd5b600160a060020a038085166000818152600c6020908152604080832080548890039055878516808452818420805489019055848452602283528184203390961684529490915290819020805486900390557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b60025433600160a060020a0390811691161461164f57600080fd5b60025460a060020a900460ff161561166657600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055600a81905560078054600181016116a1838261569a565b5060009182526020822001555034600555565b600160a060020a03338116600090815260156020908152604080832086845290915280822054603354929384938493849392849216906306011b14908a9085908b905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401608060405180830381600087803b151561173757600080fd5b5af1151561174457600080fd5b5050506040518051906020018051906020018051906020018051600254949a509298509096509094505060a060020a900460ff16151561178357600080fd5b6000861161179057600080fd5b821561179b57600080fd5b6117a58288614072565b905060638111156117e057600160a060020a03331660009081526021602090815260408083208b84529091529020548111156117e057600080fd5b6117ea338561408c565b60008511156118075761180733611802338b8b614143565b6141eb565b33600160a060020a03811660009081526015602090815260408083208c8452909152908190208390557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b91908a908a90518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15050505050505050565b60116020526000908152604090205481565b600081565b60055481565b600160a060020a0333166000908152600b60205260409020548111156118d657600080fd5b600160a060020a0333166000818152600b6020526040908190208054849003905582156108fc0290839051600060405180830381858888f19350505050151561191e57600080fd5b50565b60025460009033600160a060020a0390811691161461193f57600080fd5b60285442901061194e57600080fd5b602b5460a060020a900460ff161561196557600080fd5b50602a544281019080151561197657fe5b8160001943014008602c5550602b805474ff0000000000000000000000000000000000000000191660a060020a179055565b60045481565b600160a060020a033316600090815260126020908152604080832054600854600d8452828520600019808401875294529184205484938493019083908382805b858311611a9f575050600160a060020a0333166000818152600d60209081526040808320858452825280832054938352600f825280832085845290915290205460ff1681158015611a3d575080155b15611a4a57839150611a4e565b8193505b6006805484908110611a5c57fe5b90600052602060002090015482600885815481101515611a7857fe5b90600052602060002090015402811515611a8e57fe5b0494909401936001909201916119ee565b509298949750929550929350505050565b60025433600160a060020a03908116911614611acb57600080fd5b600082118015611adc5750600a8211155b1515611ae757600080fd5b600081118015611af85750600a8111155b1515611b0357600080fd5b600391909155600455565b600160a060020a03331660009081526014602052604081205481908190819081908190429010611b3d57600080fd5b33600160a060020a031687600160a060020a031614151515611b5e57600080fd5b600160a060020a03871660009081526023602052604090205460ff1615611b8457600080fd5b611b8e338861423f565b600160a060020a038a16600090815260146020526040902054929850909650945042901115611c1857603354600160a060020a03166394b67b1c8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611bff57600080fd5b5af11515611c0c57600080fd5b50505060405180519550505b84861115611dfe57600160a060020a03331660009081526014602052604090206107084201905583611c49886121a1565b1115611d4557611c5887614370565b925082841115611c9557600160a060020a0387166000908152600c6020526040812080548587039081900390915581548190039091559150611cc1565b50600160a060020a0386166000908152600c602052604081208054858503908101909155815481019091555b33600160a060020a0381166000908152600c6020526040908190208054870190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f91908990600190889051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611dde565b7fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f33886001611d738b6121a1565b604051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611db2876121a1565b600160a060020a033381166000908152600c602052604080822080549094019093559089168152908120555b600160a060020a0387166000908152601060205260409020429055611e7b565b33600160a060020a038116600090815260146020526040808220426102580190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f92918a91819051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a15b50505050505050565b60025460a060020a900460ff1681565b60008042602d5410151515611ea857600080fd5b60008311611eb557600080fd5b611ec16103e8846143c7565b915081611ecd336121a1565b1015611ed857600080fd5b611ee2338361408c565b50600160a060020a0333166000908152602660205260409020602e54600282015414611f6b5760006001808301829055602e5460028401819055825260276020526040909120805490918101611f38838261569a565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b805460018201541415611f89578054600101611f8782826156be565b505b60408051908101604052603054808252840160001901602082015260018281018054918201905582548391908110611fbd57fe5b906000526020600020906002020160008201518155602082015160019091015550506030805490920190915550565b602854602954602a54602b54602c54600160a060020a0390911691929394565b612014615688565b61201c615688565b6000612026615688565b61202e615688565b600160a060020a0386166000908152602660205260408120602e5460028201549195501415610c0a5783600101546040518059106120695750595b90808252806020026020018201604052509250836001015460405180591061208e5750595b90808252806020026020018201604052509150600090505b8360010154811015610c0a5783548490829081106120c057fe5b9060005260206000209060020201600001548382815181106120de57fe5b6020908102909101015283548490829081106120f657fe5b90600052602060002090600202016001015482828151811061211457fe5b602090810290910101526001016120a6565b61212e615688565b6025600083815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561219557602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311612177575b50505050509050919050565b60006121ac82614370565b600160a060020a0383166000908152600c6020526040902054019050919050565b60025433600160a060020a039081169116146121e857600080fd5b8015612201576121f78261148e565b1561220157600080fd5b600160a060020a03919091166000908152602360205260409020805460ff1916911515919091179055565b6000806000806000806000804260285410151561224857600080fd5b602b54600160a060020a03161561225e57600080fd5b602954600090815260176020526040902054600160a060020a03161561228357600080fd5b602b5460a060020a900460ff16151561229e5761229e611921565b600160a060020a038a161561234057600160a060020a038a16600090815260246020526040812060018101549099501180156122dd5750876001015489105b80156122ee57506029548860020154145b1561234057875488908a90811061230157fe5b906000526020600020906002020196508660000154602c541015801561232d57508660010154602c5411155b156123405761233b8a6143f2565b612474565b600095505b60295460009081526025602052604090205486101561247457602954600090815260256020526040902080548790811061237b57fe5b6000918252602080832090910154600160a060020a03168083526024909152604082206001810154815492985090965060001901945085919081106123bc57fe5b906000526020600020906002020160000154602c5410158015612400575083548490849081106123e857fe5b906000526020600020906002020160010154602c5411155b1561246957600091505b836001015482101561246957835484908390811061242457fe5b906000526020600020906002020190508060000154602c541015801561245057508060010154602c5411155b1561245e5761233b856143f2565b60019091019061240a565b600190950194612345565b50505050505050505050565b60025433600160a060020a0390811691161461249b57600080fd5b603354600160a060020a03166297b6078260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156124e257600080fd5b5af115156124ef57600080fd5b50505060405180519050151561250457600080fd5b600081815260176020526040902054600160a060020a03161561252657600080fd5b4282901061253357600080fd5b6029541561255257602b54600160a060020a0316151561255257600080fd5b602b80546000602c81905574ffffffffffffffffffffffffffffffffffffffffff19909116909155602a55602891909155602955565b600160a060020a033316600090815260156020908152604080832085845290915281205490808080808686108015906125c15750600087115b15156125cc57600080fd5b600160a060020a0333811660009081526015602090815260408083208c8452909152908190209789900397889055603354909116906306011b14908a9089908b905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401608060405180830381600087803b151561264e57600080fd5b5af1151561265b57600080fd5b505050604051805190602001805190602001805190602001805160335494995092975090955090935050600160a060020a03166341e34be98960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156126ca57600080fd5b5af115156126d757600080fd5b5050506040518051905015156126ec57600080fd5b600460038402046126fc33614370565b33600160a060020a031660009081526010602090815260408083204290558254939094019283018255600c9052918220805482019055915084111561274f5761274f3361274a338b8b614143565b614556565b600082111561277d57600160a060020a0333166000908152600b602052604090208054600460038502040190555b7f9c8076df639d56f1ef3ca3d4d8dc6ed089f8c4756bc5bf5d574f1cec4ef13c543389896040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15050505050505050565b60025460009033600160a060020a039081169116146127fe57600080fd5b50806128098161461a565b61281281614bc0565b6033805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905550565b60015481565b6000806000806000806000806000603360009054906101000a9004600160a060020a0316600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156128a757600080fd5b5af115156128b457600080fd5b5050506040518051906020018051919650909450505b83851161297957600160a060020a038a166000908152601560209081526040808320888452909152902054612902908b9087906151b7565b600160a060020a038b166000908152601560209081526040808320898452909152902054930192612936908b908790615269565b600160a060020a038b16600090815260156020908152604080832089845290915290205491019061296a908b9087906152ec565b600190950194909101906128ca565b600160a060020a038a16600090815260146020526040902054429011156129fb57603354600160a060020a03166394b67b1c8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156129e257600080fd5b5af115156129ef57600080fd5b50505060405180519250505b600160a060020a03999099166000908152601460205260409020549199909897509095509350505050565b6000808083851115612a3757600080fd5b600160a060020a033316600090815260136020526040902054851015612a5c57600080fd5b6009548410612a6a57600080fd5b8491505b838211612ae4576007805483908110612a8357fe5b6000918252602080832090910154600160a060020a0333168352600e825260408084208685529092529120546009805485908110612abd57fe5b90600052602060002090015402811515612ad357fe5b049290920191600190910190612a6e565b600160a060020a033381166000908152601360205260409020600186019055861615801590612b25575033600160a060020a031686600160a060020a031614155b15612ba55750600160a060020a0385166000908152600b602052604090819020805460648504908101909155907f676f0fffb2fbfbfc8daa0d0f7d89788003ac6a87c448c7fb792ceb5b8e00e0dd9087903390849051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15b600160a060020a0333166000908152600b602052604090208054919093030190915550505050565b600254600160a060020a031681565b6000808080808086881115612bf057600080fd5b600160a060020a033316600090815260126020526040902054881015612c1557600080fd5b6008548710612c2357600080fd5b600160a060020a0333166000908152600d60209081526040808320601283528184205460001901845290915290205494508793505b868411612d0c57600160a060020a0333166000818152600d60209081526040808320888452825280832054938352600f825280832088845290915290205490935060ff16915082158015612caa575081155b15612cb757849250612cbb565b8294505b6006805485908110612cc957fe5b90600052602060002090015483600886815481101515612ce557fe5b90600052602060002090015402811515612cfb57fe5b049590950194600190930192612c58565b600160a060020a0333166000908152600d602090815260408083208a8452909152902054158015612d615750600160a060020a0333166000908152600f602090815260408083208a845290915290205460ff16155b8015612d6d5750600085115b15612d9957600160a060020a0333166000908152600d602090815260408083208a845290915290208590555b600160a060020a033381166000908152601260205260409020600189019055891615801590612dda575033600160a060020a031689600160a060020a031614155b15612e5a5750600160a060020a0388166000908152600b602052604090819020805460648804908101909155907f676f0fffb2fbfbfc8daa0d0f7d89788003ac6a87c448c7fb792ceb5b8e00e0dd908a903390849051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15b600160a060020a0333166000908152600b602052604090208054919096030190945550505050505050565b60008060008060008060008042602d54101515612ea157600080fd5b603154600160a060020a031615612eb757600080fd5b60315460a060020a900460ff161515612ed257612ed26114bb565b600160a060020a038a1615612f6f57600160a060020a038a1660009081526026602052604081206001810154909950118015612f115750876001015489105b8015612f225750602e548860020154145b15612f6f57875488908a908110612f3557fe5b90600052602060002090600202019650866000015460325410158015612f615750866001015460325411155b15612f6f5761233b8a615371565b600095505b602e5460009081526027602052604090205486101561247457602e546000908152602760205260409020805487908110612faa57fe5b6000918252602080832090910154600160a060020a0316808352602690915260408220600181015481549298509096506000190194508591908110612feb57fe5b9060005260206000209060020201600001546032541015801561302f5750835484908490811061301757fe5b90600052602060002090600202016001015460325411155b1561309857600091505b836001015482101561309857835484908390811061305357fe5b9060005260206000209060020201905080600001546032541015801561307f5750806001015460325411155b1561308d5761233b85615371565b600190910190613039565b600190950194612f74565b60035481565b60408051908101604052600381527f476f6f0000000000000000000000000000000000000000000000000000000000602082015281565b603354600090819081908190819081908190600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561313757600080fd5b5af1151561314457600080fd5b505050604051805190602001805190602001805160008c815260176020526040902054939a5091985090965050600160a060020a0316935083151561318857600080fd5b6000861161319557600080fd5b61319e33614030565b6131aa33888888613d69565b6131b384614030565b6131bf848888886153e1565b600088815260186020908152604080832054600160a060020a0333168452600b909252909120549093503401839010156131f857600080fd5b3483111561322657600160a060020a0333166000908152600b60205260409020805434850390039055613250565b8234111561325057600160a060020a0333166000908152600b602052604090208054348590030190555b505060058054601483049081018255600254600160a060020a039081166000908152600b60208181526040808420805460328a049081019091559c845260178252808420805433871673ffffffffffffffffffffffffffffffffffffffff199091161790556018825280842060049789029790970490965596909216815294529220805492909601900301909355505050565b6132ed338261408c565b600160a060020a0333166000908152600e6020908152604080832060078054600019908101865291909352922080548401905580548392810190811061332f57fe5b60009182526020909120018054909101905550565b603354600090819081908190819081908190600160a060020a03166328a42e9d8960405160e060020a63ffffffff8416028152600481019190915260240160c060405180830381600087803b151561339b57600080fd5b5af115156133a857600080fd5b5050506040518051906020018051906020018051906020018051906020018051906020018051600254969d50949b5092995090975095509093505060a060020a900460ff1615156133f857600080fd5b6000841161340557600080fd5b600160a060020a03331660009081526016602090815260408083208b845290915290205460ff161561343657600080fd5b600082111561347157600160a060020a033316600090815260166020908152604080832085845290915290205460ff16151561347157600080fd5b60008611156134ff57600160a060020a0333166000908152600b60205260409020543401869010156134a257600080fd5b348611156134cc57600160a060020a0333166000908152600b602052604090208054348803900390555b506005805460328704808803909101909155600254600160a060020a03166000908152600b602052604090208054820190555b613509338861408c565b61351533868686613d69565b505050600160a060020a033316600090815260166020908152604080832097835296905294909420805460ff1916600117905550505050565b602d54602f54603054603154603254600160a060020a0390911691929394565b600a5481565b600061357f33614030565b600160a060020a0333166000908152600c60205260409020548211156135a457600080fd5b600160a060020a033381166000818152600c60205260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b61361a615688565b613622615688565b61362a615688565b613632615688565b60335460009081908190600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561367857600080fd5b5af1151561368557600080fd5b5050506040518051905060405180591061369c5750595b9080825280602002602001820160405250603354909550600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156136ef57600080fd5b5af115156136fc57600080fd5b505050604051805190506040518059106137135750595b9080825280602002602001820160405250603354909450600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561376557600080fd5b5af1151561377257600080fd5b5050506040518051906020018051919450909250505b8183116137fa57600083815260176020526040902054600160a060020a03168582815181106137b357fe5b600160a060020a0390921660209283029091018201526000848152601890915260409020548482815181106137e457fe5b6020908102909101015260019283019201613788565b5092959194509092505050565b600080426028541015151561381b57600080fd5b6000831161382857600080fd5b6138346103e8846143c7565b915081613840336121a1565b101561384b57600080fd5b613855338361408c565b50600160a060020a03331660009081526024602052604090206029546002820154146138de5760006001808301829055602954600284018190558252602560205260409091208054909181016138ab838261569a565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b8054600182015414156138fc5780546001016138fa82826156be565b505b60408051908101604052602a5480825284016000190160208201526001828101805491820190558254839190811061393057fe5b90600052602060002090600202016000820151815560208201516001909101555050602a805490920190915550565b60025460009033600160a060020a0390811691161461397d57600080fd5b506003546005805460649281029290920491829003905560068054600181016139a6838261569a565b9160005260206000209001600060015490919091505550600880548060010182816139d1919061569a565b50600091825260209091200155620151804201600a55565b6139f1615688565b6027600083815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561219557602002820191906000526020600020908154600160a060020a031681526001909101906020018083116121775750505050509050919050565b600160a060020a0333811660009081526015602090815260408083208684529091528082205460335492938493849384939284928392839291909116906306011b14908c9087908d905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401608060405180830381600087803b1515613aec57600080fd5b5af11515613af957600080fd5b5050506040518051906020018051906020018051906020018051600254949c50929a509098509096505060a060020a900460ff161515613b3857600080fd5b60008811613b4557600080fd5b600160a060020a0333166000908152600b6020526040902054340185901015613b6d57600080fd5b34851115613b9757600160a060020a0333166000908152600b602052604090208054348703900390555b603285049250600483860360058054929091049182019055600254600160a060020a03166000908152600b602052604090208054850190559150613bdb848a614072565b90506063811115613c1657600160a060020a03331660009081526021602090815260408083208d8452909152902054811115613c1657600080fd5b613c20338761408c565b6000871115613c3857613c3833611802338d8d614143565b33600160a060020a03811660009081526015602090815260408083208e84529091529081902080548c0190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b91908c908c90518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a150505050505050505050565b600160a060020a03918216600090815260226020908152604080832093909416825291909152205490565b60025460009033600160a060020a03908116911614613d1357600080fd5b50600454600580546064928102929092049182900390556007805460018101613d3c838261569a565b5060009182526020822001556009805460018101613d5a838261569a565b50600091825260209091200155565b6000831515613dd95750600160a060020a03841660008181526019602090815260408083208684528252808320805486019055838352601a8252808320868452825280832054938352601582528083208684529091529020548202600a90910102613dd485826141eb565b614029565b8360011415613eb157600160a060020a038086166000818152601a602090815260408083208884528252808320805488019055928252601981528282208783529052819020546033549092169063c46e3e859086905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613e6257600080fd5b5af11515613e6f57600080fd5b5050506040518051600160a060020a038816600090815260156020908152604080832089845290915290205485029201919091029150613dd4905085826141eb565b8360021415613ee857600160a060020a0385166000908152601b602090815260408083208684529091529020805483019055614029565b8360031415613f1f57600160a060020a0385166000908152601c602090815260408083208684529091529020805483019055614029565b8360041415613f5657600160a060020a0385166000908152601d602090815260408083208684529091529020805483019055614029565b8360051415613f8d57600160a060020a0385166000908152601e602090815260408083208684529091529020805483019055614029565b8360061415613fc457600160a060020a0385166000908152601f602090815260408083208684529091529020805483019055614029565b8360071415613ff957600160a060020a0385166000908152602080805260408083208684529091529020805483019055614029565b836008141561402957600160a060020a038516600090815260216020908152604080832086845290915290208290555b5050505050565b600061403b82614370565b600160a060020a039092166000908152601060209081526040808320429055825485018355600c9091529020805490920190915550565b60008282018381101561408157fe5b8091505b5092915050565b600080600061409a85614370565b9250828411156140f957600160a060020a0385166000908152600c60205260409020548385039250829010156140cf57600080fd5b600080548390038155600160a060020a0386168152600c6020526040902080548390039055614123565b50600080548484039081018255600160a060020a0386168252600c60205260409091208054820190555b50505050600160a060020a03166000908152601060205260409020429055565b600160a060020a038084166000818152601a6020908152604080832087845282528083205493835260198252808320878452909152808220546033549294600a909401939092169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156141c757600080fd5b5af115156141d457600080fd5b505050604051805190500183020290509392505050565b806141f58361148e565b600160a060020a039093166000818152600d602090815260408083206008805485529083528184209590970190945594549181526011909452922091909155600180549091019055565b6033546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561428e57600080fd5b5af1151561429b57600080fd5b5050506040518051906020018051919650909450505b83851161436057600160a060020a038a1660009081526015602090815260408083208884529091529020546142e9908b9087906151b7565b600160a060020a038b16600090815260156020908152604080832089845290915290205493019261431d908b908790615269565b600160a060020a038a166000908152601560209081526040808320898452909152902054910190614351908a9087906152ec565b600190950194909101906142b1565b9199909850909650945050505050565b600160a060020a038116600090815260106020526040812054818111801561439757504281105b156143bc5760648142036143aa8561148e565b028115156143b457fe5b0491506143c1565b600091505b50919050565b6000808315156143da5760009150614085565b508282028284828115156143ea57fe5b041461408157fe5b602b8054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283168117909355602980546000908152601760205260408082208054909516909517909355603354905492938493849360149316916357f1f6ca91905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561448857600080fd5b5af1151561449557600080fd5b505050604051805190506015028115156144ab57fe5b602954600090815260186020526040902091900490556144ca84614030565b603354602954600160a060020a039091169063275babee9060405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561451857600080fd5b5af1151561452557600080fd5b5050506040518051906020018051906020018051929550909350909150614550905084848484613d69565b50505050565b6000806145628461148e565b915061456e8284615676565b90508015156145c357600160a060020a0384166000818152600f60209081526040808320600880548552908352818420805460ff19166001179055938352600d825280832093548352929052908120556145ec565b600160a060020a0384166000908152600d60209081526040808320600854845290915290208190555b5050600854600160a060020a0390921660009081526011602052604090209190915560018054919091039055565b6033546000908190600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561465d57600080fd5b5af1151561466a57600080fd5b5050506040518051906020018051919350909150505b8082116148245782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156146cd57600080fd5b5af115156146da57600080fd5b5050506040518051603354909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561472d57600080fd5b5af1151561473a57600080fd5b5050506040518051905014151561475057600080fd5b82600160a060020a031663c46e3e858360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561479657600080fd5b5af115156147a357600080fd5b5050506040518051603354909150600160a060020a031663c46e3e858460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156147f657600080fd5b5af1151561480357600080fd5b5050506040518051905014151561481957600080fd5b600190910190614680565b603354600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561486257600080fd5b5af1151561486f57600080fd5b5050506040518051906020018051919350909150505b808211614bbb5782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156148d257600080fd5b5af115156148df57600080fd5b5050506040518051603354909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561493257600080fd5b5af1151561493f57600080fd5b5050506040518051905014151561495557600080fd5b82600160a060020a03166369632f568360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561499b57600080fd5b5af115156149a857600080fd5b5050506040518051603354909150600160a060020a03166369632f568460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156149fb57600080fd5b5af11515614a0857600080fd5b50505060405180519050141515614a1e57600080fd5b82600160a060020a03166321446cfe8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614a6457600080fd5b5af11515614a7157600080fd5b5050506040518051603354909150600160a060020a03166321446cfe8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614ac457600080fd5b5af11515614ad157600080fd5b50505060405180519050141515614ae757600080fd5b82600160a060020a0316636101a1f78360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614b2d57600080fd5b5af11515614b3a57600080fd5b5050506040518051603354909150600160a060020a0316636101a1f78460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614b8d57600080fd5b5af11515614b9a57600080fd5b50505060405180519050141515614bb057600080fd5b600190910190614885565b505050565b6033546000908190819081908190819081908190600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515614c0f57600080fd5b5af11515614c1c57600080fd5b5050506040518051906020018051919950909750505b8688116150315788600160a060020a0316637e0be7e38960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614c7f57600080fd5b5af11515614c8c57600080fd5b5050506040518051603354909150600160a060020a0316637e0be7e38a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614cdf57600080fd5b5af11515614cec57600080fd5b50505060405180519050141515614d0257600080fd5b88600160a060020a031663f48aa0448960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614d4857600080fd5b5af11515614d5557600080fd5b5050506040518051603354909150600160a060020a031663f48aa0448a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614da857600080fd5b5af11515614db557600080fd5b50505060405180519050141515614dcb57600080fd5b88600160a060020a031663309ba1208960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614e1157600080fd5b5af11515614e1e57600080fd5b5050506040518051603354909150600160a060020a031663309ba1208a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614e7157600080fd5b5af11515614e7e57600080fd5b50505060405180519050141515614e9457600080fd5b88600160a060020a03166372fecf848960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614eda57600080fd5b5af11515614ee757600080fd5b5050506040518051603354909150600160a060020a03166372fecf848a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614f3a57600080fd5b5af11515614f4757600080fd5b50505060405180519050141515614f5d57600080fd5b88600160a060020a0316630caeb3508960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614fa357600080fd5b5af11515614fb057600080fd5b5050506040518051603354909150600160a060020a0316630caeb3508a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561500357600080fd5b5af1151561501057600080fd5b5050506040518051905014151561502657600080fd5b600190970196614c32565b603354600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561506f57600080fd5b5af1151561507c57600080fd5b5050506040518051906020018051919950909750505b8688116151ac57603354600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b15156150e157600080fd5b5af115156150ee57600080fd5b505050604051805190602001805190602001805192985090965090945050600160a060020a03891663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561515257600080fd5b5af1151561515f57600080fd5b50505060405180519060200180519060200180519295509093509091505085831461518957600080fd5b84821461519557600080fd5b8381146151a157600080fd5b600190970196615092565b505050505050505050565b600160a060020a038084166000818152601c60209081526040808320878452825280832054938352601b8252808320878452909152808220546033549294600a9485019391929116906369632f569088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561523c57600080fd5b5af1151561524957600080fd5b505050604051805190500184020281151561526057fe5b04949350505050565b600160a060020a03808416600081815260208080526040808320878452825280832054938352601f8252808320878452909152808220546033549294600a948501939192911690636101a1f79088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561523c57600080fd5b600160a060020a038084166000818152601e60209081526040808320878452825280832054938352601d8252808320878452909152808220546033549294600a9485019391929116906321446cfe9088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561523c57600080fd5b6031805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790556153a281614030565b6153b48161180283602f546001614143565b600160a060020a03166000908152601560209081526040808320602f548452909152902080546001019055565b600083151561544d5750600160a060020a0384166000818152601960209081526040808320868452825280832080548690039055838352601a8252808320868452825280832054938352601582528083208684529091529020548202600a90910102613dd48582614556565b836001141561552657600160a060020a038086166000818152601a60209081526040808320888452825280832080548890039055928252601981528282208783529052819020546033549092169063c46e3e859086905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156154d757600080fd5b5af115156154e457600080fd5b5050506040518051600160a060020a038816600090815260156020908152604080832089845290915290205485029201919091029150613dd490508582614556565b836002141561555e57600160a060020a0385166000908152601b60209081526040808320868452909152902080548390039055614029565b836003141561559657600160a060020a0385166000908152601c60209081526040808320868452909152902080548390039055614029565b83600414156155ce57600160a060020a0385166000908152601d60209081526040808320868452909152902080548390039055614029565b836005141561560657600160a060020a0385166000908152601e60209081526040808320868452909152902080548390039055614029565b836006141561563e57600160a060020a0385166000908152601f60209081526040808320868452909152902080548390039055614029565b836007141561402957600160a060020a0385166000908152602080805260408083208684529091529020805483900390555050505050565b60008282111561568257fe5b50900390565b60206040519081016040526000815290565b815481835581811511614bbb57600083815260209020614bbb9181019083016156ea565b815481835581811511614bbb57600202816002028360005260206000209182019101614bbb9190615708565b61140591905b8082111561570457600081556001016156f0565b5090565b61140591905b80821115615704576000808255600182015560020161570e5600a165627a7a723058208057da4d208b614eacaa1130285e8cb6b121808fad9dad42962a710dfd2634ac0029
Deployed Bytecode
0x6060604052600436106102795763ffffffff60e060020a60003504166302b68bbf811461028357806306fdde031461033b578063095ea7b3146103c55780630b407022146103fb57806313aa7b6f146104335780631746bd1b1461046a578063179fc99f1461055557806318160ddd1461058657806318d801681461059957806319e9e5de146105b257806322bfba59146105d157806323b872dd146105e457806325a7650a1461060c5780632bfd2e06146106175780633081fe3f14610630578063313ce5671461064f57806338198c65146106785780633bed33ce1461068b5780634a1d08af146106a15780634a617fba146106b45780634efdd4f9146106c757806353dd8881146106da5780635dc22cce146106f35780635e123ce41461071257806360f61a4c1461072557806364f54a171461073b5780636a7d1a7e146107885780636c20d755146107a757806370a082311461081057806370bc52fb1461082f57806370d9f7dc14610853578063716e560414610875578063751fef651461088e5780637c85a757146108a75780637ef58e73146108c657806380fa7902146108d95780638d4777c8146109235780638da5cb5b146109485780638fafb286146109775780639323eaad1461099c57806393d7c6bf146109be57806395d89b41146109d15780639e30dd5f146109e4578063a21f74b8146109ef578063a5a2cb1914610a05578063a7b7f1d414610a10578063a89cdad914610a23578063a9059cbb14610a36578063b1d6600314610a58578063b912950e14610a6b578063c38f074114610a81578063c9c286c614610a94578063d8737d8a14610aaa578063dd62ed3e14610ab8578063f2f921e614610add575b6005805434019055005b341561028e57600080fd5b6102a2600160a060020a0360043516610af0565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156102e65780820151838201526020016102ce565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561032557808201518382015260200161030d565b5050505090500194505050505060405180910390f35b341561034657600080fd5b61034e610c16565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561038a578082015183820152602001610372565b50505050905090810190601f1680156103b75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103d057600080fd5b6103e7600160a060020a0360043516602435610c4d565b604051901515815260200160405180910390f35b341561040657600080fd5b6104316024600480358281019290820135918135808301929082013591604435918201910135610cb9565b005b341561043e57600080fd5b610446610f59565b60405180848152602001838152602001828152602001935050505060405180910390f35b341561047557600080fd5b61047d610ffe565b604051808c81526020018b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156104f75780820151838201526020016104df565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561053657808201518382015260200161051e565b505050509050019d505050505050505050505050505060405180910390f35b341561056057600080fd5b610574600160a060020a03600435166113e6565b60405190815260200160405180910390f35b341561059157600080fd5b610574611401565b34156105a457600080fd5b610431600435602435611408565b34156105bd57600080fd5b610574600160a060020a036004351661148e565b34156105dc57600080fd5b6104316114bb565b34156105ef57600080fd5b6103e7600160a060020a0360043581169060243516604435611542565b610431600435611634565b341561062257600080fd5b6104316004356024356116b4565b341561063b57600080fd5b610574600160a060020a0360043516611894565b341561065a57600080fd5b6106626118a6565b60405160ff909116815260200160405180910390f35b341561068357600080fd5b6105746118ab565b341561069657600080fd5b6104316004356118b1565b34156106ac57600080fd5b610431611921565b34156106bf57600080fd5b6105746119a8565b34156106d257600080fd5b6104466119ae565b34156106e557600080fd5b610431600435602435611ab0565b34156106fe57600080fd5b610431600160a060020a0360043516611b0e565b341561071d57600080fd5b6103e7611e84565b341561073057600080fd5b610431600435611e94565b341561074657600080fd5b61074e611fec565b6040519485526020850193909352604080850192909252600160a060020a03166060840152608083019190915260a0909101905180910390f35b341561079357600080fd5b6102a2600160a060020a036004351661200c565b34156107b257600080fd5b6107bd600435612126565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107fc5780820151838201526020016107e4565b505050509050019250505060405180910390f35b341561081b57600080fd5b610574600160a060020a03600435166121a1565b341561083a57600080fd5b610431600160a060020a036004351660243515156121cd565b341561085e57600080fd5b610431600160a060020a036004351660243561222c565b341561088057600080fd5b610431600435602435612480565b341561089957600080fd5b610431600435602435612588565b34156108b257600080fd5b610431600160a060020a03600435166127e0565b34156108d157600080fd5b610574612842565b34156108e457600080fd5b6108f8600160a060020a0360043516612848565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b341561092e57600080fd5b610431600160a060020a0360043516602435604435612a26565b341561095357600080fd5b61095b612bcd565b604051600160a060020a03909116815260200160405180910390f35b341561098257600080fd5b610431600160a060020a0360043516602435604435612bdc565b34156109a757600080fd5b610431600160a060020a0360043516602435612e85565b34156109c957600080fd5b6105746130a3565b34156109dc57600080fd5b61034e6130a9565b6104316004356130e0565b34156109fa57600080fd5b6104316004356132e3565b610431600435613344565b3415610a1b57600080fd5b61074e61354e565b3415610a2e57600080fd5b61057461356e565b3415610a4157600080fd5b6103e7600160a060020a0360043516602435613574565b3415610a6357600080fd5b6102a2613612565b3415610a7657600080fd5b610431600435613807565b3415610a8c57600080fd5b61043161395f565b3415610a9f57600080fd5b6107bd6004356139e9565b610431600435602435613a62565b3415610ac357600080fd5b610574600160a060020a0360043581169060243516613cca565b3415610ae857600080fd5b610431613cf5565b610af8615688565b610b00615688565b6000610b0a615688565b610b12615688565b600160a060020a038616600090815260246020526040812060295460028201549195501415610c0a578360010154604051805910610b4d5750595b908082528060200260200182016040525092508360010154604051805910610b725750595b90808252806020026020018201604052509150600090505b8360010154811015610c0a578354849082908110610ba457fe5b906000526020600020906002020160000154838281518110610bc257fe5b602090810290910101528354849082908110610bda57fe5b906000526020600020906002020160010154828281518110610bf857fe5b60209081029091010152600101610b8a565b50909590945092505050565b60408051908101604052600781527f49646c6545746800000000000000000000000000000000000000000000000000602082015281565b600160a060020a03338116600081815260226020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b6002546000908190819081908190819033600160a060020a03908116911614610ce157600080fd5b60025460a060020a900460ff1615610cf857600080fd5b600095505b86861015610f4b578b8b87818110610d1157fe5b90506020020135600160a060020a031694508989878181101515610d3157fe5b60335460209091029290920135955050600160a060020a03166372fecf848560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610d8657600080fd5b5af11515610d9357600080fd5b5050506040518051935050600083118015610dd25750600160a060020a038516600090815260166020908152604080832087845290915290205460ff16155b15610f4057603354600160a060020a031663309ba1208560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610e1f57600080fd5b5af11515610e2c57600080fd5b5050506040518051603354909350600160a060020a03169050630caeb3508560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610e8157600080fd5b5af11515610e8e57600080fd5b505050604051805190509050610ea685838584613d69565b600160a060020a03851660009081526016602090815260408083208784529091529020805460ff191660011790557fb84e528e18e54dd4bb87635427809661099f52b6fb31e5c969e6f07c9a19913c85858a8a8a818110610f0357fe5b905060200201356040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15b600190950194610cfd565b505050505050505050505050565b600160a060020a033316600090815260136020526040812054600954829182916000190182825b828111610ff3576007805482908110610f9557fe5b6000918252602080832090910154600160a060020a0333168352600e825260408084208585529092529120546009805484908110610fcf57fe5b90600052602060002090015402811515610fe557fe5b049190910190600101610f80565b509591945092509050565b6000806000806000806000806000611014615688565b61101c615688565b611024615688565b61102c615688565b60335460009081908190600160a060020a0316638975e45f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561107257600080fd5b5af1151561107f57600080fd5b505050604051805190506040518059106110965750595b9080825280602002602001820160405250603354909550600160a060020a031663f10a98486040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156110e957600080fd5b5af115156110f657600080fd5b5050506040518051905060405180591061110d5750595b9080825280602002602001820160405250603354909450600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561115f57600080fd5b5af1151561116c57600080fd5b5050506040518051906020018051919450909250505b8183116111cf57600160a060020a03331660009081526015602090815260408083208684529091529020548582815181106111b957fe5b6020908102909101015260019283019201611182565b603354600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561120d57600080fd5b5af1151561121a57600080fd5b5050506040518051906020018051919450909250505b81831161127d57600160a060020a033316600090815260156020908152604080832086845290915290205485828151811061126757fe5b6020908102909101015260019283019201611230565b50603354600090600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156112bf57600080fd5b5af115156112cc57600080fd5b5050506040518051906020018051919450909250505b81831161133757600160a060020a033316600090815260166020908152604080832086845290915290205460ff1684828151811061131c57fe5b911515602092830290910190910152600192830192016112e2565b600554600154600780544293929190600019810190811061135457fe5b6000918252602080832090910154600160a060020a03339081168452600e835260408085206007546000190186529093529190922054600a549091611398906121a1565b33600160a060020a0381166000908152600b6020526040902054906113bc9061148e565b8d8d9f509f509f509f509f509f509f509f509f509f509f505050505050909192939495969798999a565b600160a060020a03166000908152600b602052604090205490565b6000545b90565b60025433600160a060020a0390811691161461142357600080fd5b4282901061143057600080fd5b602f541561144f57603154600160a060020a0316151561144f57600080fd5b603180546000603281905574ffffffffffffffffffffffffffffffffffffffffff19909116909155603055602d91909155602f55602e80546001019055565b600160a060020a03166000908152600d602090815260408083206011835281842054845290915290205490565b60025460009033600160a060020a039081169116146114d957600080fd5b602d544290106114e857600080fd5b60315460a060020a900460ff16156114ff57600080fd5b506030544281019080151561151057fe5b8160001943014008603255506031805474ff0000000000000000000000000000000000000000191660a060020a179055565b600061154d84614030565b600160a060020a0380851660009081526022602090815260408083203390941683529290522054821180159061159b5750600160a060020a0384166000908152600c60205260409020548211155b15156115a657600080fd5b600160a060020a038085166000818152600c6020908152604080832080548890039055878516808452818420805489019055848452602283528184203390961684529490915290819020805486900390557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b60025433600160a060020a0390811691161461164f57600080fd5b60025460a060020a900460ff161561166657600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055600a81905560078054600181016116a1838261569a565b5060009182526020822001555034600555565b600160a060020a03338116600090815260156020908152604080832086845290915280822054603354929384938493849392849216906306011b14908a9085908b905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401608060405180830381600087803b151561173757600080fd5b5af1151561174457600080fd5b5050506040518051906020018051906020018051906020018051600254949a509298509096509094505060a060020a900460ff16151561178357600080fd5b6000861161179057600080fd5b821561179b57600080fd5b6117a58288614072565b905060638111156117e057600160a060020a03331660009081526021602090815260408083208b84529091529020548111156117e057600080fd5b6117ea338561408c565b60008511156118075761180733611802338b8b614143565b6141eb565b33600160a060020a03811660009081526015602090815260408083208c8452909152908190208390557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b91908a908a90518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15050505050505050565b60116020526000908152604090205481565b600081565b60055481565b600160a060020a0333166000908152600b60205260409020548111156118d657600080fd5b600160a060020a0333166000818152600b6020526040908190208054849003905582156108fc0290839051600060405180830381858888f19350505050151561191e57600080fd5b50565b60025460009033600160a060020a0390811691161461193f57600080fd5b60285442901061194e57600080fd5b602b5460a060020a900460ff161561196557600080fd5b50602a544281019080151561197657fe5b8160001943014008602c5550602b805474ff0000000000000000000000000000000000000000191660a060020a179055565b60045481565b600160a060020a033316600090815260126020908152604080832054600854600d8452828520600019808401875294529184205484938493019083908382805b858311611a9f575050600160a060020a0333166000818152600d60209081526040808320858452825280832054938352600f825280832085845290915290205460ff1681158015611a3d575080155b15611a4a57839150611a4e565b8193505b6006805484908110611a5c57fe5b90600052602060002090015482600885815481101515611a7857fe5b90600052602060002090015402811515611a8e57fe5b0494909401936001909201916119ee565b509298949750929550929350505050565b60025433600160a060020a03908116911614611acb57600080fd5b600082118015611adc5750600a8211155b1515611ae757600080fd5b600081118015611af85750600a8111155b1515611b0357600080fd5b600391909155600455565b600160a060020a03331660009081526014602052604081205481908190819081908190429010611b3d57600080fd5b33600160a060020a031687600160a060020a031614151515611b5e57600080fd5b600160a060020a03871660009081526023602052604090205460ff1615611b8457600080fd5b611b8e338861423f565b600160a060020a038a16600090815260146020526040902054929850909650945042901115611c1857603354600160a060020a03166394b67b1c8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611bff57600080fd5b5af11515611c0c57600080fd5b50505060405180519550505b84861115611dfe57600160a060020a03331660009081526014602052604090206107084201905583611c49886121a1565b1115611d4557611c5887614370565b925082841115611c9557600160a060020a0387166000908152600c6020526040812080548587039081900390915581548190039091559150611cc1565b50600160a060020a0386166000908152600c602052604081208054858503908101909155815481019091555b33600160a060020a0381166000908152600c6020526040908190208054870190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f91908990600190889051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611dde565b7fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f33886001611d738b6121a1565b604051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611db2876121a1565b600160a060020a033381166000908152600c602052604080822080549094019093559089168152908120555b600160a060020a0387166000908152601060205260409020429055611e7b565b33600160a060020a038116600090815260146020526040808220426102580190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f92918a91819051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a15b50505050505050565b60025460a060020a900460ff1681565b60008042602d5410151515611ea857600080fd5b60008311611eb557600080fd5b611ec16103e8846143c7565b915081611ecd336121a1565b1015611ed857600080fd5b611ee2338361408c565b50600160a060020a0333166000908152602660205260409020602e54600282015414611f6b5760006001808301829055602e5460028401819055825260276020526040909120805490918101611f38838261569a565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b805460018201541415611f89578054600101611f8782826156be565b505b60408051908101604052603054808252840160001901602082015260018281018054918201905582548391908110611fbd57fe5b906000526020600020906002020160008201518155602082015160019091015550506030805490920190915550565b602854602954602a54602b54602c54600160a060020a0390911691929394565b612014615688565b61201c615688565b6000612026615688565b61202e615688565b600160a060020a0386166000908152602660205260408120602e5460028201549195501415610c0a5783600101546040518059106120695750595b90808252806020026020018201604052509250836001015460405180591061208e5750595b90808252806020026020018201604052509150600090505b8360010154811015610c0a5783548490829081106120c057fe5b9060005260206000209060020201600001548382815181106120de57fe5b6020908102909101015283548490829081106120f657fe5b90600052602060002090600202016001015482828151811061211457fe5b602090810290910101526001016120a6565b61212e615688565b6025600083815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561219557602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311612177575b50505050509050919050565b60006121ac82614370565b600160a060020a0383166000908152600c6020526040902054019050919050565b60025433600160a060020a039081169116146121e857600080fd5b8015612201576121f78261148e565b1561220157600080fd5b600160a060020a03919091166000908152602360205260409020805460ff1916911515919091179055565b6000806000806000806000804260285410151561224857600080fd5b602b54600160a060020a03161561225e57600080fd5b602954600090815260176020526040902054600160a060020a03161561228357600080fd5b602b5460a060020a900460ff16151561229e5761229e611921565b600160a060020a038a161561234057600160a060020a038a16600090815260246020526040812060018101549099501180156122dd5750876001015489105b80156122ee57506029548860020154145b1561234057875488908a90811061230157fe5b906000526020600020906002020196508660000154602c541015801561232d57508660010154602c5411155b156123405761233b8a6143f2565b612474565b600095505b60295460009081526025602052604090205486101561247457602954600090815260256020526040902080548790811061237b57fe5b6000918252602080832090910154600160a060020a03168083526024909152604082206001810154815492985090965060001901945085919081106123bc57fe5b906000526020600020906002020160000154602c5410158015612400575083548490849081106123e857fe5b906000526020600020906002020160010154602c5411155b1561246957600091505b836001015482101561246957835484908390811061242457fe5b906000526020600020906002020190508060000154602c541015801561245057508060010154602c5411155b1561245e5761233b856143f2565b60019091019061240a565b600190950194612345565b50505050505050505050565b60025433600160a060020a0390811691161461249b57600080fd5b603354600160a060020a03166297b6078260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156124e257600080fd5b5af115156124ef57600080fd5b50505060405180519050151561250457600080fd5b600081815260176020526040902054600160a060020a03161561252657600080fd5b4282901061253357600080fd5b6029541561255257602b54600160a060020a0316151561255257600080fd5b602b80546000602c81905574ffffffffffffffffffffffffffffffffffffffffff19909116909155602a55602891909155602955565b600160a060020a033316600090815260156020908152604080832085845290915281205490808080808686108015906125c15750600087115b15156125cc57600080fd5b600160a060020a0333811660009081526015602090815260408083208c8452909152908190209789900397889055603354909116906306011b14908a9089908b905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401608060405180830381600087803b151561264e57600080fd5b5af1151561265b57600080fd5b505050604051805190602001805190602001805190602001805160335494995092975090955090935050600160a060020a03166341e34be98960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156126ca57600080fd5b5af115156126d757600080fd5b5050506040518051905015156126ec57600080fd5b600460038402046126fc33614370565b33600160a060020a031660009081526010602090815260408083204290558254939094019283018255600c9052918220805482019055915084111561274f5761274f3361274a338b8b614143565b614556565b600082111561277d57600160a060020a0333166000908152600b602052604090208054600460038502040190555b7f9c8076df639d56f1ef3ca3d4d8dc6ed089f8c4756bc5bf5d574f1cec4ef13c543389896040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15050505050505050565b60025460009033600160a060020a039081169116146127fe57600080fd5b50806128098161461a565b61281281614bc0565b6033805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905550565b60015481565b6000806000806000806000806000603360009054906101000a9004600160a060020a0316600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156128a757600080fd5b5af115156128b457600080fd5b5050506040518051906020018051919650909450505b83851161297957600160a060020a038a166000908152601560209081526040808320888452909152902054612902908b9087906151b7565b600160a060020a038b166000908152601560209081526040808320898452909152902054930192612936908b908790615269565b600160a060020a038b16600090815260156020908152604080832089845290915290205491019061296a908b9087906152ec565b600190950194909101906128ca565b600160a060020a038a16600090815260146020526040902054429011156129fb57603354600160a060020a03166394b67b1c8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156129e257600080fd5b5af115156129ef57600080fd5b50505060405180519250505b600160a060020a03999099166000908152601460205260409020549199909897509095509350505050565b6000808083851115612a3757600080fd5b600160a060020a033316600090815260136020526040902054851015612a5c57600080fd5b6009548410612a6a57600080fd5b8491505b838211612ae4576007805483908110612a8357fe5b6000918252602080832090910154600160a060020a0333168352600e825260408084208685529092529120546009805485908110612abd57fe5b90600052602060002090015402811515612ad357fe5b049290920191600190910190612a6e565b600160a060020a033381166000908152601360205260409020600186019055861615801590612b25575033600160a060020a031686600160a060020a031614155b15612ba55750600160a060020a0385166000908152600b602052604090819020805460648504908101909155907f676f0fffb2fbfbfc8daa0d0f7d89788003ac6a87c448c7fb792ceb5b8e00e0dd9087903390849051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15b600160a060020a0333166000908152600b602052604090208054919093030190915550505050565b600254600160a060020a031681565b6000808080808086881115612bf057600080fd5b600160a060020a033316600090815260126020526040902054881015612c1557600080fd5b6008548710612c2357600080fd5b600160a060020a0333166000908152600d60209081526040808320601283528184205460001901845290915290205494508793505b868411612d0c57600160a060020a0333166000818152600d60209081526040808320888452825280832054938352600f825280832088845290915290205490935060ff16915082158015612caa575081155b15612cb757849250612cbb565b8294505b6006805485908110612cc957fe5b90600052602060002090015483600886815481101515612ce557fe5b90600052602060002090015402811515612cfb57fe5b049590950194600190930192612c58565b600160a060020a0333166000908152600d602090815260408083208a8452909152902054158015612d615750600160a060020a0333166000908152600f602090815260408083208a845290915290205460ff16155b8015612d6d5750600085115b15612d9957600160a060020a0333166000908152600d602090815260408083208a845290915290208590555b600160a060020a033381166000908152601260205260409020600189019055891615801590612dda575033600160a060020a031689600160a060020a031614155b15612e5a5750600160a060020a0388166000908152600b602052604090819020805460648804908101909155907f676f0fffb2fbfbfc8daa0d0f7d89788003ac6a87c448c7fb792ceb5b8e00e0dd908a903390849051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15b600160a060020a0333166000908152600b602052604090208054919096030190945550505050505050565b60008060008060008060008042602d54101515612ea157600080fd5b603154600160a060020a031615612eb757600080fd5b60315460a060020a900460ff161515612ed257612ed26114bb565b600160a060020a038a1615612f6f57600160a060020a038a1660009081526026602052604081206001810154909950118015612f115750876001015489105b8015612f225750602e548860020154145b15612f6f57875488908a908110612f3557fe5b90600052602060002090600202019650866000015460325410158015612f615750866001015460325411155b15612f6f5761233b8a615371565b600095505b602e5460009081526027602052604090205486101561247457602e546000908152602760205260409020805487908110612faa57fe5b6000918252602080832090910154600160a060020a0316808352602690915260408220600181015481549298509096506000190194508591908110612feb57fe5b9060005260206000209060020201600001546032541015801561302f5750835484908490811061301757fe5b90600052602060002090600202016001015460325411155b1561309857600091505b836001015482101561309857835484908390811061305357fe5b9060005260206000209060020201905080600001546032541015801561307f5750806001015460325411155b1561308d5761233b85615371565b600190910190613039565b600190950194612f74565b60035481565b60408051908101604052600381527f476f6f0000000000000000000000000000000000000000000000000000000000602082015281565b603354600090819081908190819081908190600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561313757600080fd5b5af1151561314457600080fd5b505050604051805190602001805190602001805160008c815260176020526040902054939a5091985090965050600160a060020a0316935083151561318857600080fd5b6000861161319557600080fd5b61319e33614030565b6131aa33888888613d69565b6131b384614030565b6131bf848888886153e1565b600088815260186020908152604080832054600160a060020a0333168452600b909252909120549093503401839010156131f857600080fd5b3483111561322657600160a060020a0333166000908152600b60205260409020805434850390039055613250565b8234111561325057600160a060020a0333166000908152600b602052604090208054348590030190555b505060058054601483049081018255600254600160a060020a039081166000908152600b60208181526040808420805460328a049081019091559c845260178252808420805433871673ffffffffffffffffffffffffffffffffffffffff199091161790556018825280842060049789029790970490965596909216815294529220805492909601900301909355505050565b6132ed338261408c565b600160a060020a0333166000908152600e6020908152604080832060078054600019908101865291909352922080548401905580548392810190811061332f57fe5b60009182526020909120018054909101905550565b603354600090819081908190819081908190600160a060020a03166328a42e9d8960405160e060020a63ffffffff8416028152600481019190915260240160c060405180830381600087803b151561339b57600080fd5b5af115156133a857600080fd5b5050506040518051906020018051906020018051906020018051906020018051906020018051600254969d50949b5092995090975095509093505060a060020a900460ff1615156133f857600080fd5b6000841161340557600080fd5b600160a060020a03331660009081526016602090815260408083208b845290915290205460ff161561343657600080fd5b600082111561347157600160a060020a033316600090815260166020908152604080832085845290915290205460ff16151561347157600080fd5b60008611156134ff57600160a060020a0333166000908152600b60205260409020543401869010156134a257600080fd5b348611156134cc57600160a060020a0333166000908152600b602052604090208054348803900390555b506005805460328704808803909101909155600254600160a060020a03166000908152600b602052604090208054820190555b613509338861408c565b61351533868686613d69565b505050600160a060020a033316600090815260166020908152604080832097835296905294909420805460ff1916600117905550505050565b602d54602f54603054603154603254600160a060020a0390911691929394565b600a5481565b600061357f33614030565b600160a060020a0333166000908152600c60205260409020548211156135a457600080fd5b600160a060020a033381166000818152600c60205260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b61361a615688565b613622615688565b61362a615688565b613632615688565b60335460009081908190600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561367857600080fd5b5af1151561368557600080fd5b5050506040518051905060405180591061369c5750595b9080825280602002602001820160405250603354909550600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156136ef57600080fd5b5af115156136fc57600080fd5b505050604051805190506040518059106137135750595b9080825280602002602001820160405250603354909450600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561376557600080fd5b5af1151561377257600080fd5b5050506040518051906020018051919450909250505b8183116137fa57600083815260176020526040902054600160a060020a03168582815181106137b357fe5b600160a060020a0390921660209283029091018201526000848152601890915260409020548482815181106137e457fe5b6020908102909101015260019283019201613788565b5092959194509092505050565b600080426028541015151561381b57600080fd5b6000831161382857600080fd5b6138346103e8846143c7565b915081613840336121a1565b101561384b57600080fd5b613855338361408c565b50600160a060020a03331660009081526024602052604090206029546002820154146138de5760006001808301829055602954600284018190558252602560205260409091208054909181016138ab838261569a565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b8054600182015414156138fc5780546001016138fa82826156be565b505b60408051908101604052602a5480825284016000190160208201526001828101805491820190558254839190811061393057fe5b90600052602060002090600202016000820151815560208201516001909101555050602a805490920190915550565b60025460009033600160a060020a0390811691161461397d57600080fd5b506003546005805460649281029290920491829003905560068054600181016139a6838261569a565b9160005260206000209001600060015490919091505550600880548060010182816139d1919061569a565b50600091825260209091200155620151804201600a55565b6139f1615688565b6027600083815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561219557602002820191906000526020600020908154600160a060020a031681526001909101906020018083116121775750505050509050919050565b600160a060020a0333811660009081526015602090815260408083208684529091528082205460335492938493849384939284928392839291909116906306011b14908c9087908d905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401608060405180830381600087803b1515613aec57600080fd5b5af11515613af957600080fd5b5050506040518051906020018051906020018051906020018051600254949c50929a509098509096505060a060020a900460ff161515613b3857600080fd5b60008811613b4557600080fd5b600160a060020a0333166000908152600b6020526040902054340185901015613b6d57600080fd5b34851115613b9757600160a060020a0333166000908152600b602052604090208054348703900390555b603285049250600483860360058054929091049182019055600254600160a060020a03166000908152600b602052604090208054850190559150613bdb848a614072565b90506063811115613c1657600160a060020a03331660009081526021602090815260408083208d8452909152902054811115613c1657600080fd5b613c20338761408c565b6000871115613c3857613c3833611802338d8d614143565b33600160a060020a03811660009081526015602090815260408083208e84529091529081902080548c0190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b91908c908c90518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a150505050505050505050565b600160a060020a03918216600090815260226020908152604080832093909416825291909152205490565b60025460009033600160a060020a03908116911614613d1357600080fd5b50600454600580546064928102929092049182900390556007805460018101613d3c838261569a565b5060009182526020822001556009805460018101613d5a838261569a565b50600091825260209091200155565b6000831515613dd95750600160a060020a03841660008181526019602090815260408083208684528252808320805486019055838352601a8252808320868452825280832054938352601582528083208684529091529020548202600a90910102613dd485826141eb565b614029565b8360011415613eb157600160a060020a038086166000818152601a602090815260408083208884528252808320805488019055928252601981528282208783529052819020546033549092169063c46e3e859086905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613e6257600080fd5b5af11515613e6f57600080fd5b5050506040518051600160a060020a038816600090815260156020908152604080832089845290915290205485029201919091029150613dd4905085826141eb565b8360021415613ee857600160a060020a0385166000908152601b602090815260408083208684529091529020805483019055614029565b8360031415613f1f57600160a060020a0385166000908152601c602090815260408083208684529091529020805483019055614029565b8360041415613f5657600160a060020a0385166000908152601d602090815260408083208684529091529020805483019055614029565b8360051415613f8d57600160a060020a0385166000908152601e602090815260408083208684529091529020805483019055614029565b8360061415613fc457600160a060020a0385166000908152601f602090815260408083208684529091529020805483019055614029565b8360071415613ff957600160a060020a0385166000908152602080805260408083208684529091529020805483019055614029565b836008141561402957600160a060020a038516600090815260216020908152604080832086845290915290208290555b5050505050565b600061403b82614370565b600160a060020a039092166000908152601060209081526040808320429055825485018355600c9091529020805490920190915550565b60008282018381101561408157fe5b8091505b5092915050565b600080600061409a85614370565b9250828411156140f957600160a060020a0385166000908152600c60205260409020548385039250829010156140cf57600080fd5b600080548390038155600160a060020a0386168152600c6020526040902080548390039055614123565b50600080548484039081018255600160a060020a0386168252600c60205260409091208054820190555b50505050600160a060020a03166000908152601060205260409020429055565b600160a060020a038084166000818152601a6020908152604080832087845282528083205493835260198252808320878452909152808220546033549294600a909401939092169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156141c757600080fd5b5af115156141d457600080fd5b505050604051805190500183020290509392505050565b806141f58361148e565b600160a060020a039093166000818152600d602090815260408083206008805485529083528184209590970190945594549181526011909452922091909155600180549091019055565b6033546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561428e57600080fd5b5af1151561429b57600080fd5b5050506040518051906020018051919650909450505b83851161436057600160a060020a038a1660009081526015602090815260408083208884529091529020546142e9908b9087906151b7565b600160a060020a038b16600090815260156020908152604080832089845290915290205493019261431d908b908790615269565b600160a060020a038a166000908152601560209081526040808320898452909152902054910190614351908a9087906152ec565b600190950194909101906142b1565b9199909850909650945050505050565b600160a060020a038116600090815260106020526040812054818111801561439757504281105b156143bc5760648142036143aa8561148e565b028115156143b457fe5b0491506143c1565b600091505b50919050565b6000808315156143da5760009150614085565b508282028284828115156143ea57fe5b041461408157fe5b602b8054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283168117909355602980546000908152601760205260408082208054909516909517909355603354905492938493849360149316916357f1f6ca91905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561448857600080fd5b5af1151561449557600080fd5b505050604051805190506015028115156144ab57fe5b602954600090815260186020526040902091900490556144ca84614030565b603354602954600160a060020a039091169063275babee9060405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561451857600080fd5b5af1151561452557600080fd5b5050506040518051906020018051906020018051929550909350909150614550905084848484613d69565b50505050565b6000806145628461148e565b915061456e8284615676565b90508015156145c357600160a060020a0384166000818152600f60209081526040808320600880548552908352818420805460ff19166001179055938352600d825280832093548352929052908120556145ec565b600160a060020a0384166000908152600d60209081526040808320600854845290915290208190555b5050600854600160a060020a0390921660009081526011602052604090209190915560018054919091039055565b6033546000908190600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561465d57600080fd5b5af1151561466a57600080fd5b5050506040518051906020018051919350909150505b8082116148245782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156146cd57600080fd5b5af115156146da57600080fd5b5050506040518051603354909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561472d57600080fd5b5af1151561473a57600080fd5b5050506040518051905014151561475057600080fd5b82600160a060020a031663c46e3e858360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561479657600080fd5b5af115156147a357600080fd5b5050506040518051603354909150600160a060020a031663c46e3e858460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156147f657600080fd5b5af1151561480357600080fd5b5050506040518051905014151561481957600080fd5b600190910190614680565b603354600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561486257600080fd5b5af1151561486f57600080fd5b5050506040518051906020018051919350909150505b808211614bbb5782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156148d257600080fd5b5af115156148df57600080fd5b5050506040518051603354909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561493257600080fd5b5af1151561493f57600080fd5b5050506040518051905014151561495557600080fd5b82600160a060020a03166369632f568360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561499b57600080fd5b5af115156149a857600080fd5b5050506040518051603354909150600160a060020a03166369632f568460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156149fb57600080fd5b5af11515614a0857600080fd5b50505060405180519050141515614a1e57600080fd5b82600160a060020a03166321446cfe8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614a6457600080fd5b5af11515614a7157600080fd5b5050506040518051603354909150600160a060020a03166321446cfe8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614ac457600080fd5b5af11515614ad157600080fd5b50505060405180519050141515614ae757600080fd5b82600160a060020a0316636101a1f78360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614b2d57600080fd5b5af11515614b3a57600080fd5b5050506040518051603354909150600160a060020a0316636101a1f78460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614b8d57600080fd5b5af11515614b9a57600080fd5b50505060405180519050141515614bb057600080fd5b600190910190614885565b505050565b6033546000908190819081908190819081908190600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515614c0f57600080fd5b5af11515614c1c57600080fd5b5050506040518051906020018051919950909750505b8688116150315788600160a060020a0316637e0be7e38960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614c7f57600080fd5b5af11515614c8c57600080fd5b5050506040518051603354909150600160a060020a0316637e0be7e38a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614cdf57600080fd5b5af11515614cec57600080fd5b50505060405180519050141515614d0257600080fd5b88600160a060020a031663f48aa0448960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614d4857600080fd5b5af11515614d5557600080fd5b5050506040518051603354909150600160a060020a031663f48aa0448a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614da857600080fd5b5af11515614db557600080fd5b50505060405180519050141515614dcb57600080fd5b88600160a060020a031663309ba1208960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614e1157600080fd5b5af11515614e1e57600080fd5b5050506040518051603354909150600160a060020a031663309ba1208a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614e7157600080fd5b5af11515614e7e57600080fd5b50505060405180519050141515614e9457600080fd5b88600160a060020a03166372fecf848960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614eda57600080fd5b5af11515614ee757600080fd5b5050506040518051603354909150600160a060020a03166372fecf848a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614f3a57600080fd5b5af11515614f4757600080fd5b50505060405180519050141515614f5d57600080fd5b88600160a060020a0316630caeb3508960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515614fa357600080fd5b5af11515614fb057600080fd5b5050506040518051603354909150600160a060020a0316630caeb3508a60405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561500357600080fd5b5af1151561501057600080fd5b5050506040518051905014151561502657600080fd5b600190970196614c32565b603354600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561506f57600080fd5b5af1151561507c57600080fd5b5050506040518051906020018051919950909750505b8688116151ac57603354600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b15156150e157600080fd5b5af115156150ee57600080fd5b505050604051805190602001805190602001805192985090965090945050600160a060020a03891663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561515257600080fd5b5af1151561515f57600080fd5b50505060405180519060200180519060200180519295509093509091505085831461518957600080fd5b84821461519557600080fd5b8381146151a157600080fd5b600190970196615092565b505050505050505050565b600160a060020a038084166000818152601c60209081526040808320878452825280832054938352601b8252808320878452909152808220546033549294600a9485019391929116906369632f569088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561523c57600080fd5b5af1151561524957600080fd5b505050604051805190500184020281151561526057fe5b04949350505050565b600160a060020a03808416600081815260208080526040808320878452825280832054938352601f8252808320878452909152808220546033549294600a948501939192911690636101a1f79088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561523c57600080fd5b600160a060020a038084166000818152601e60209081526040808320878452825280832054938352601d8252808320878452909152808220546033549294600a9485019391929116906321446cfe9088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561523c57600080fd5b6031805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790556153a281614030565b6153b48161180283602f546001614143565b600160a060020a03166000908152601560209081526040808320602f548452909152902080546001019055565b600083151561544d5750600160a060020a0384166000818152601960209081526040808320868452825280832080548690039055838352601a8252808320868452825280832054938352601582528083208684529091529020548202600a90910102613dd48582614556565b836001141561552657600160a060020a038086166000818152601a60209081526040808320888452825280832080548890039055928252601981528282208783529052819020546033549092169063c46e3e859086905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156154d757600080fd5b5af115156154e457600080fd5b5050506040518051600160a060020a038816600090815260156020908152604080832089845290915290205485029201919091029150613dd490508582614556565b836002141561555e57600160a060020a0385166000908152601b60209081526040808320868452909152902080548390039055614029565b836003141561559657600160a060020a0385166000908152601c60209081526040808320868452909152902080548390039055614029565b83600414156155ce57600160a060020a0385166000908152601d60209081526040808320868452909152902080548390039055614029565b836005141561560657600160a060020a0385166000908152601e60209081526040808320868452909152902080548390039055614029565b836006141561563e57600160a060020a0385166000908152601f60209081526040808320868452909152902080548390039055614029565b836007141561402957600160a060020a0385166000908152602080805260408083208684529091529020805483900390555050505050565b60008282111561568257fe5b50900390565b60206040519081016040526000815290565b815481835581811511614bbb57600083815260209020614bbb9181019083016156ea565b815481835581811511614bbb57600202816002028360005260206000209182019101614bbb9190615708565b61140591905b8082111561570457600081556001016156f0565b5090565b61140591905b80821115615704576000808255600182015560020161570e5600a165627a7a723058208057da4d208b614eacaa1130285e8cb6b121808fad9dad42962a710dfd2634ac0029
Swarm Source
bzzr://8057da4d208b614eacaa1130285e8cb6b121808fad9dad42962a710dfd2634ac
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.
Add Token to MetaMask (Web3)