CentrallyIssuedToken
Deploy on AlchemyContract Information
The following smart contract is a CentrallyIssuedToken contract that inherits from BurnableToken and UpgradeableToken contracts. It is used to create a token with a specified name, symbol, total supply, and decimals. The token is centrally issued, meaning that the owner of the contract initially holds all the tokens. The contract also includes a function to burn tokens.
More Info
/*
* ERC20 interface
* see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 {
uint public totalSupply;
function balanceOf(address who) constant returns (uint);
function allowance(address owner, address spender) constant returns (uint);
function transfer(address to, uint value) returns (bool ok);
function transferFrom(address from, address to, uint value) returns (bool ok);
function approve(address spender, uint value) returns (bool ok);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
/**
* Math operations with safety checks
*/
contract SafeMath {
function safeMul(uint a, uint b) internal returns (uint) {
uint c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function safeDiv(uint a, uint b) internal returns (uint) {
assert(b > 0);
uint c = a / b;
assert(a == b * c + a % b);
return c;
}
function safeSub(uint a, uint b) internal returns (uint) {
assert(b <= a);
return a - b;
}
function safeAdd(uint a, uint b) internal returns (uint) {
uint c = a + b;
assert(c>=a && c>=b);
return c;
}
function max64(uint64 a, uint64 b) internal constant returns (uint64) {
return a >= b ? a : b;
}
function min64(uint64 a, uint64 b) internal constant returns (uint64) {
return a < b ? a : b;
}
function max256(uint256 a, uint256 b) internal constant returns (uint256) {
return a >= b ? a : b;
}
function min256(uint256 a, uint256 b) internal constant returns (uint256) {
return a < b ? a : b;
}
function assert(bool assertion) internal {
if (!assertion) {
throw;
}
}
}
/**
* Standard ERC20 token with Short Hand Attack and approve() race condition mitigation.
*
* Based on code by FirstBlood:
* https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, SafeMath {
mapping(address => uint) balances;
mapping (address => mapping (address => uint)) allowed;
// Interface marker
bool public constant isToken = true;
/**
*
* Fix for the ERC20 short address attack
*
* http://vessenes.com/the-erc20-short-address-attack-explained/
*/
modifier onlyPayloadSize(uint size) {
if(msg.data.length < size + 4) {
throw;
}
_;
}
function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) returns (bool success) {
balances[msg.sender] = safeSub(balances[msg.sender], _value);
balances[_to] = safeAdd(balances[_to], _value);
Transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint _value) returns (bool success) {
var _allowance = allowed[_from][msg.sender];
// Check is not needed because safeSub(_allowance, _value) will already throw if this condition is not met
// if (_value > _allowance) throw;
balances[_to] = safeAdd(balances[_to], _value);
balances[_from] = safeSub(balances[_from], _value);
allowed[_from][msg.sender] = safeSub(_allowance, _value);
Transfer(_from, _to, _value);
return true;
}
function balanceOf(address _owner) constant returns (uint balance) {
return balances[_owner];
}
function approve(address _spender, uint _value) returns (bool success) {
// To change the approve amount you first have to reduce the addresses`
// allowance to zero by calling `approve(_spender, 0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw;
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) constant returns (uint remaining) {
return allowed[_owner][_spender];
}
}
/**
* A trait that allows any token owner to decrease the token supply.
*
* We add a Burned event to differentiate from normal transfers.
* However, we still try to support some legacy Ethereum ecocsystem,
* as ERC-20 has not standardized on the burn event yet.
*
*/
contract BurnableToken is StandardToken {
address public constant BURN_ADDRESS = 0;
/** How many tokens we burned */
event Burned(address burner, uint burnedAmount);
/**
* Burn extra tokens from a balance.
*
*/
function burn(uint burnAmount) {
address burner = msg.sender;
balances[burner] = safeSub(balances[burner], burnAmount);
totalSupply = safeSub(totalSupply, burnAmount);
Burned(burner, burnAmount);
// Keep token balance tracking services happy by sending the burned amount to
// "burn address", so that it will show up as a ERC-20 transaction
// in etherscan, etc. as there is no standarized burn event yet
Transfer(burner, BURN_ADDRESS, burnAmount);
}
}
/**
* Upgrade agent interface inspired by Lunyr.
*
* Upgrade agent transfers tokens to a new contract.
* Upgrade agent itself can be the token contract, or just a middle man contract doing the heavy lifting.
*/
contract UpgradeAgent {
uint public originalSupply;
/** Interface marker */
function isUpgradeAgent() public constant returns (bool) {
return true;
}
function upgradeFrom(address _from, uint256 _value) public;
}
/**
* A token upgrade mechanism where users can opt-in amount of tokens to the next smart contract revision.
*
* First envisioned by Golem and Lunyr projects.
*/
contract UpgradeableToken is StandardToken {
/** Contract / person who can set the upgrade path. This can be the same as team multisig wallet, as what it is with its default value. */
address public upgradeMaster;
/** The next contract where the tokens will be migrated. */
UpgradeAgent public upgradeAgent;
/** How many tokens we have upgraded by now. */
uint256 public totalUpgraded;
/**
* Upgrade states.
*
* - NotAllowed: The child contract has not reached a condition where the upgrade can bgun
* - WaitingForAgent: Token allows upgrade, but we don't have a new agent yet
* - ReadyToUpgrade: The agent is set, but not a single token has been upgraded yet
* - Upgrading: Upgrade agent is set and the balance holders can upgrade their tokens
*
*/
enum UpgradeState {Unknown, NotAllowed, WaitingForAgent, ReadyToUpgrade, Upgrading}
/**
* Somebody has upgraded some of his tokens.
*/
event Upgrade(address indexed _from, address indexed _to, uint256 _value);
/**
* New upgrade agent available.
*/
event UpgradeAgentSet(address agent);
/**
* Do not allow construction without upgrade master set.
*/
function UpgradeableToken(address _upgradeMaster) {
upgradeMaster = _upgradeMaster;
}
/**
* Allow the token holder to upgrade some of their tokens to a new contract.
*/
function upgrade(uint256 value) public {
UpgradeState state = getUpgradeState();
if(!(state == UpgradeState.ReadyToUpgrade || state == UpgradeState.Upgrading)) {
// Called in a bad state
throw;
}
// Validate input value.
if (value == 0) throw;
balances[msg.sender] = safeSub(balances[msg.sender], value);
// Take tokens out from circulation
totalSupply = safeSub(totalSupply, value);
totalUpgraded = safeAdd(totalUpgraded, value);
// Upgrade agent reissues the tokens
upgradeAgent.upgradeFrom(msg.sender, value);
Upgrade(msg.sender, upgradeAgent, value);
}
/**
* Set an upgrade agent that handles
*/
function setUpgradeAgent(address agent) external {
if(!canUpgrade()) {
// The token is not yet in a state that we could think upgrading
throw;
}
if (agent == 0x0) throw;
// Only a master can designate the next agent
if (msg.sender != upgradeMaster) throw;
// Upgrade has already begun for an agent
if (getUpgradeState() == UpgradeState.Upgrading) throw;
upgradeAgent = UpgradeAgent(agent);
// Bad interface
if(!upgradeAgent.isUpgradeAgent()) throw;
// Make sure that token supplies match in source and target
if (upgradeAgent.originalSupply() != totalSupply) throw;
UpgradeAgentSet(upgradeAgent);
}
/**
* Get the state of the token upgrade.
*/
function getUpgradeState() public constant returns(UpgradeState) {
if(!canUpgrade()) return UpgradeState.NotAllowed;
else if(address(upgradeAgent) == 0x00) return UpgradeState.WaitingForAgent;
else if(totalUpgraded == 0) return UpgradeState.ReadyToUpgrade;
else return UpgradeState.Upgrading;
}
/**
* Change the upgrade master.
*
* This allows us to set a new owner for the upgrade mechanism.
*/
function setUpgradeMaster(address master) public {
if (master == 0x0) throw;
if (msg.sender != upgradeMaster) throw;
upgradeMaster = master;
}
/**
* Child contract can enable to provide the condition when the upgrade can begun.
*/
function canUpgrade() public constant returns(bool) {
return true;
}
}
/**
* Centrally issued Ethereum token.
*
* We mix in burnable and upgradeable traits.
*
* Token supply is created in the token contract creation and allocated to owner.
* The owner can then transfer from its supply to crowdsale participants.
* The owner, or anybody, can burn any excessive tokens they are holding.
*
*/
contract CentrallyIssuedToken is BurnableToken, UpgradeableToken {
string public name;
string public symbol;
uint public decimals;
function CentrallyIssuedToken(address _owner, string _name, string _symbol, uint _totalSupply, uint _decimals) UpgradeableToken(_owner) {
name = _name;
symbol = _symbol;
totalSupply = _totalSupply;
decimals = _decimals;
// Allocate initial balance to the owner
balances[_owner] = _totalSupply;
}
}
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"burnAmount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"upgrade","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"upgradeAgent","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"upgradeMaster","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getUpgradeState","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"canUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalUpgraded","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"agent","type":"address"}],"name":"setUpgradeAgent","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"isToken","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"BURN_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"master","type":"address"}],"name":"setUpgradeMaster","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_owner","type":"address"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_totalSupply","type":"uint256"},{"name":"_decimals","type":"uint256"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Upgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"agent","type":"address"}],"name":"UpgradeAgentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"burner","type":"address"},{"indexed":false,"name":"burnedAmount","type":"uint256"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"burnAmount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"upgrade","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"upgradeAgent","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"upgradeMaster","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getUpgradeState","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"canUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalUpgraded","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"agent","type":"address"}],"name":"setUpgradeAgent","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"isToken","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"BURN_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"master","type":"address"}],"name":"setUpgradeMaster","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_owner","type":"address"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_totalSupply","type":"uint256"},{"name":"_decimals","type":"uint256"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Upgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"agent","type":"address"}],"name":"UpgradeAgentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"burner","type":"address"},{"indexed":false,"name":"burnedAmount","type":"uint256"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]
6060604052346100005760405162000fb338038062000fb383398101604090815281516020830151918301516060840151608085015192949384019391909101915b845b60038054600160a060020a031916600160a060020a0383161790555b508360069080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ac57805160ff19168380011785556100d9565b828001600101855582156100d9579182015b828111156100d95782518255916020019190600101906100be565b5b506100fa9291505b808211156100f657600081556001016100e2565b5090565b50508260079080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061014857805160ff1916838001178555610175565b82800160010185558215610175579182015b8281111561017557825182559160200191906001019061015a565b5b506101969291505b808211156100f657600081556001016100e2565b5090565b505060008281556008829055600160a060020a03861681526001602052604090208290555b50505050505b610de280620001d16000396000f300606060405236156100f65763ffffffff60e060020a60003504166306fdde0381146100fb578063095ea7b31461018857806318160ddd146101b857806323b872dd146101d7578063313ce5671461020d57806342966c681461022c57806345977d031461023e5780635de4ccb014610250578063600440cb1461027957806370a08231146102a25780638444b391146102cd57806395d89b41146102fb5780639738968c14610388578063a9059cbb146103a9578063c752ff62146103d9578063d7e7088a146103f8578063dd62ed3e14610413578063eefa597b14610444578063fccc281314610465578063ffeb7d751461048e575b610000565b34610000576101086104a9565b60408051602080825283518183015283519192839290830191850190808383821561014e575b80518252602083111561014e57601f19909201916020918201910161012e565b505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576101a4600160a060020a0360043516602435610537565b604080519115158252519081900360200190f35b34610000576101c56105dd565b60408051918252519081900360200190f35b34610000576101a4600160a060020a03600435811690602435166044356105e3565b604080519115158252519081900360200190f35b34610000576101c56106e6565b60408051918252519081900360200190f35b346100005761023c6004356106ec565b005b346100005761023c6004356107c4565b005b346100005761025d610927565b60408051600160a060020a039092168252519081900360200190f35b346100005761025d610936565b60408051600160a060020a039092168252519081900360200190f35b34610000576101c5600160a060020a0360043516610945565b60408051918252519081900360200190f35b34610000576102da610964565b6040518082600481116100005760ff16815260200191505060405180910390f35b34610000576101086109b1565b60408051602080825283518183015283519192839290830191850190808383821561014e575b80518252602083111561014e57601f19909201916020918201910161012e565b505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576101a4610a3f565b604080519115158252519081900360200190f35b34610000576101a4600160a060020a0360043516602435610a45565b604080519115158252519081900360200190f35b34610000576101c5610b0e565b60408051918252519081900360200190f35b346100005761023c600160a060020a0360043516610b14565b005b34610000576101c5600160a060020a0360043581169060243516610cd2565b60408051918252519081900360200190f35b34610000576101a4610cff565b604080519115158252519081900360200190f35b346100005761025d610d04565b60408051600160a060020a039092168252519081900360200190f35b346100005761023c600160a060020a0360043516610d09565b005b6006805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561052f5780601f106105045761010080835404028352916020019161052f565b820191906000526020600020905b81548152906001019060200180831161051257829003601f168201915b505050505081565b6000811580159061056c5750600160a060020a0333811660009081526002602090815260408083209387168352929052205415155b1561057657610000565b600160a060020a03338116600081815260026020908152604080832094881680845294825291829020869055815186815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906106249084610d65565b600160a060020a0380861660009081526001602052604080822093909355908716815220546106539084610d8d565b600160a060020a0386166000908152600160205260409020556106768184610d8d565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60085481565b33600160a060020a0381166000908152600160205260409020546107109083610d8d565b600160a060020a038216600090815260016020526040812091909155546107379083610d8d565b60005560408051600160a060020a03831681526020810184905281517f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7929181900390910190a1604080518381529051600091600160a060020a038416917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35b5050565b60006107ce610964565b9050600381600481116100005714806107ef57506004816004811161000057145b15156107fa57610000565b81151561080657610000565b600160a060020a0333166000908152600160205260409020546108299083610d8d565b600160a060020a033316600090815260016020526040812091909155546108509083610d8d565b6000556005546108609083610d65565b60055560048054604080517f753e88e5000000000000000000000000000000000000000000000000000000008152600160a060020a0333811694820194909452602481018690529051929091169163753e88e59160448082019260009290919082900301818387803b156100005760325a03f115610000575050600454604080518581529051600160a060020a03928316935033909216917f7e5c344a8141a805725cb476f76c6953b842222b967edd1f78ddb6e8b3f397ac9181900360200190a35b5050565b600454600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160205260409020545b919050565b600061096e610a3f565b151561097c575060016109ab565b600454600160a060020a03161515610996575060026109ab565b60055415156109a7575060036109ab565b5060045b5b5b5b90565b6007805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561052f5780601f106105045761010080835404028352916020019161052f565b820191906000526020600020905b81548152906001019060200180831161051257829003601f168201915b505050505081565b60015b90565b600060406044361015610a5757610000565b600160a060020a033316600090815260016020526040902054610a7a9084610d8d565b600160a060020a033381166000908152600160205260408082209390935590861681522054610aa99084610d65565b600160a060020a038086166000818152600160209081526040918290209490945580518781529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3600191505b5b5092915050565b60055481565b610b1c610a3f565b1515610b2757610000565b600160a060020a0381161515610b3c57610000565b60035433600160a060020a03908116911614610b5757610000565b6004610b61610964565b60048111610000571415610b7457610000565b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383811691909117808355604080516000602091820181905282517f61d3d7a6000000000000000000000000000000000000000000000000000000008152925193909416946361d3d7a69483820194929383900390910190829087803b156100005760325a03f1156100005750506040515115159050610c1557610000565b600054600460009054906101000a9004600160a060020a0316600160a060020a0316634b2ba0dd6000604051602001526040518163ffffffff1660e060020a028152600401809050602060405180830381600087803b156100005760325a03f11561000057505060405151919091149050610c8f57610000565b60045460408051600160a060020a039092168252517f7845d5aa74cc410e35571258d954f23b82276e160fe8c188fa80566580f279cc9181900360200190a15b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600181565b600081565b600160a060020a0381161515610d1e57610000565b60035433600160a060020a03908116911614610d3957610000565b6003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b6000828201610d82848210801590610d7d5750838210155b610da6565b8091505b5092915050565b6000610d9b83831115610da6565b508082035b92915050565b801515610ccf57610000565b5b505600a165627a7a723058206f2898f030ea614593dbd798eb566cb68a79473af607720237e7a4e87c33e97a002900000000000000000000000000f6bf3c5033e944feddb3dc8ffb4d47af17ef0b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a53746f726a546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000553544f524a000000000000000000000000000000000000000000000000000000
6060604052346100005760405162000fb338038062000fb383398101604090815281516020830151918301516060840151608085015192949384019391909101915b845b60038054600160a060020a031916600160a060020a0383161790555b508360069080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ac57805160ff19168380011785556100d9565b828001600101855582156100d9579182015b828111156100d95782518255916020019190600101906100be565b5b506100fa9291505b808211156100f657600081556001016100e2565b5090565b50508260079080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061014857805160ff1916838001178555610175565b82800160010185558215610175579182015b8281111561017557825182559160200191906001019061015a565b5b506101969291505b808211156100f657600081556001016100e2565b5090565b505060008281556008829055600160a060020a03861681526001602052604090208290555b50505050505b610de280620001d16000396000f300606060405236156100f65763ffffffff60e060020a60003504166306fdde0381146100fb578063095ea7b31461018857806318160ddd146101b857806323b872dd146101d7578063313ce5671461020d57806342966c681461022c57806345977d031461023e5780635de4ccb014610250578063600440cb1461027957806370a08231146102a25780638444b391146102cd57806395d89b41146102fb5780639738968c14610388578063a9059cbb146103a9578063c752ff62146103d9578063d7e7088a146103f8578063dd62ed3e14610413578063eefa597b14610444578063fccc281314610465578063ffeb7d751461048e575b610000565b34610000576101086104a9565b60408051602080825283518183015283519192839290830191850190808383821561014e575b80518252602083111561014e57601f19909201916020918201910161012e565b505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576101a4600160a060020a0360043516602435610537565b604080519115158252519081900360200190f35b34610000576101c56105dd565b60408051918252519081900360200190f35b34610000576101a4600160a060020a03600435811690602435166044356105e3565b604080519115158252519081900360200190f35b34610000576101c56106e6565b60408051918252519081900360200190f35b346100005761023c6004356106ec565b005b346100005761023c6004356107c4565b005b346100005761025d610927565b60408051600160a060020a039092168252519081900360200190f35b346100005761025d610936565b60408051600160a060020a039092168252519081900360200190f35b34610000576101c5600160a060020a0360043516610945565b60408051918252519081900360200190f35b34610000576102da610964565b6040518082600481116100005760ff16815260200191505060405180910390f35b34610000576101086109b1565b60408051602080825283518183015283519192839290830191850190808383821561014e575b80518252602083111561014e57601f19909201916020918201910161012e565b505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576101a4610a3f565b604080519115158252519081900360200190f35b34610000576101a4600160a060020a0360043516602435610a45565b604080519115158252519081900360200190f35b34610000576101c5610b0e565b60408051918252519081900360200190f35b346100005761023c600160a060020a0360043516610b14565b005b34610000576101c5600160a060020a0360043581169060243516610cd2565b60408051918252519081900360200190f35b34610000576101a4610cff565b604080519115158252519081900360200190f35b346100005761025d610d04565b60408051600160a060020a039092168252519081900360200190f35b346100005761023c600160a060020a0360043516610d09565b005b6006805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561052f5780601f106105045761010080835404028352916020019161052f565b820191906000526020600020905b81548152906001019060200180831161051257829003601f168201915b505050505081565b6000811580159061056c5750600160a060020a0333811660009081526002602090815260408083209387168352929052205415155b1561057657610000565b600160a060020a03338116600081815260026020908152604080832094881680845294825291829020869055815186815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906106249084610d65565b600160a060020a0380861660009081526001602052604080822093909355908716815220546106539084610d8d565b600160a060020a0386166000908152600160205260409020556106768184610d8d565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60085481565b33600160a060020a0381166000908152600160205260409020546107109083610d8d565b600160a060020a038216600090815260016020526040812091909155546107379083610d8d565b60005560408051600160a060020a03831681526020810184905281517f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7929181900390910190a1604080518381529051600091600160a060020a038416917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35b5050565b60006107ce610964565b9050600381600481116100005714806107ef57506004816004811161000057145b15156107fa57610000565b81151561080657610000565b600160a060020a0333166000908152600160205260409020546108299083610d8d565b600160a060020a033316600090815260016020526040812091909155546108509083610d8d565b6000556005546108609083610d65565b60055560048054604080517f753e88e5000000000000000000000000000000000000000000000000000000008152600160a060020a0333811694820194909452602481018690529051929091169163753e88e59160448082019260009290919082900301818387803b156100005760325a03f115610000575050600454604080518581529051600160a060020a03928316935033909216917f7e5c344a8141a805725cb476f76c6953b842222b967edd1f78ddb6e8b3f397ac9181900360200190a35b5050565b600454600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160205260409020545b919050565b600061096e610a3f565b151561097c575060016109ab565b600454600160a060020a03161515610996575060026109ab565b60055415156109a7575060036109ab565b5060045b5b5b5b90565b6007805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561052f5780601f106105045761010080835404028352916020019161052f565b820191906000526020600020905b81548152906001019060200180831161051257829003601f168201915b505050505081565b60015b90565b600060406044361015610a5757610000565b600160a060020a033316600090815260016020526040902054610a7a9084610d8d565b600160a060020a033381166000908152600160205260408082209390935590861681522054610aa99084610d65565b600160a060020a038086166000818152600160209081526040918290209490945580518781529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3600191505b5b5092915050565b60055481565b610b1c610a3f565b1515610b2757610000565b600160a060020a0381161515610b3c57610000565b60035433600160a060020a03908116911614610b5757610000565b6004610b61610964565b60048111610000571415610b7457610000565b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383811691909117808355604080516000602091820181905282517f61d3d7a6000000000000000000000000000000000000000000000000000000008152925193909416946361d3d7a69483820194929383900390910190829087803b156100005760325a03f1156100005750506040515115159050610c1557610000565b600054600460009054906101000a9004600160a060020a0316600160a060020a0316634b2ba0dd6000604051602001526040518163ffffffff1660e060020a028152600401809050602060405180830381600087803b156100005760325a03f11561000057505060405151919091149050610c8f57610000565b60045460408051600160a060020a039092168252517f7845d5aa74cc410e35571258d954f23b82276e160fe8c188fa80566580f279cc9181900360200190a15b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600181565b600081565b600160a060020a0381161515610d1e57610000565b60035433600160a060020a03908116911614610d3957610000565b6003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b6000828201610d82848210801590610d7d5750838210155b610da6565b8091505b5092915050565b6000610d9b83831115610da6565b508082035b92915050565b801515610ccf57610000565b5b505600a165627a7a723058206f2898f030ea614593dbd798eb566cb68a79473af607720237e7a4e87c33e97a002900000000000000000000000000f6bf3c5033e944feddb3dc8ffb4d47af17ef0b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a53746f726a546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000553544f524a000000000000000000000000000000000000000000000000000000