More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 71 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 5034258 | 2466 days ago | IN | 0 ETH | 0.00229177 | ||||
Withdraw | 5034249 | 2466 days ago | IN | 0 ETH | 0.00633496 | ||||
Withdraw | 5034241 | 2466 days ago | IN | 0 ETH | 0.00184164 | ||||
Withdraw | 5034239 | 2466 days ago | IN | 0 ETH | 0.00178964 | ||||
Withdraw | 5034235 | 2466 days ago | IN | 0 ETH | 0.00208299 | ||||
Withdraw | 5034231 | 2466 days ago | IN | 0 ETH | 0.00184912 | ||||
Withdraw | 5034216 | 2466 days ago | IN | 0 ETH | 0.0018393 | ||||
Withdraw | 5015059 | 2469 days ago | IN | 0 ETH | 0.00164437 | ||||
Withdraw | 5010406 | 2470 days ago | IN | 0 ETH | 0.00077286 | ||||
Withdraw | 5010361 | 2470 days ago | IN | 0 ETH | 0.00086768 | ||||
Withdraw | 5000470 | 2472 days ago | IN | 0 ETH | 0.00091106 | ||||
0x5f8cf7c5 | 5000394 | 2472 days ago | IN | 0 ETH | 0.00055932 | ||||
Withdraw | 5000094 | 2472 days ago | IN | 0 ETH | 0.00108058 | ||||
Withdraw | 4999556 | 2472 days ago | IN | 0 ETH | 0.00086768 | ||||
Withdraw | 4997804 | 2472 days ago | IN | 0 ETH | 0.00070388 | ||||
Withdraw | 4997035 | 2472 days ago | IN | 0 ETH | 0.00093836 | ||||
Withdraw | 4992485 | 2473 days ago | IN | 0 ETH | 0.0007026 | ||||
Withdraw | 4991975 | 2473 days ago | IN | 0 ETH | 0.00086466 | ||||
Withdraw | 4991730 | 2473 days ago | IN | 0 ETH | 0.00070388 | ||||
Transfer | 4991687 | 2473 days ago | IN | 1.47273 ETH | 0.0022394 | ||||
Transfer | 4991683 | 2473 days ago | IN | 1.613468 ETH | 0.0022394 | ||||
Transfer | 4991676 | 2473 days ago | IN | 0.140738 ETH | 0.0022394 | ||||
Withdraw | 4991670 | 2473 days ago | IN | 0 ETH | 0.00070388 | ||||
Withdraw | 4991669 | 2473 days ago | IN | 0 ETH | 0.00070388 | ||||
Withdraw | 4991668 | 2473 days ago | IN | 0 ETH | 0.00070388 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
5034258 | 2466 days ago | 8.85850304 ETH | ||||
5031289 | 2466 days ago | 0.19162854 ETH | ||||
5029982 | 2467 days ago | 0.7 ETH | ||||
5029957 | 2467 days ago | 0.71770857 ETH | ||||
5028753 | 2467 days ago | 0.1 ETH | ||||
5028435 | 2467 days ago | 0.2 ETH | ||||
5028417 | 2467 days ago | 0.2 ETH | ||||
5028411 | 2467 days ago | 0.3 ETH | ||||
5028127 | 2467 days ago | 0.97 ETH | ||||
5028096 | 2467 days ago | 0.95046684 ETH | ||||
5024359 | 2468 days ago | 0.1 ETH | ||||
5024115 | 2468 days ago | 0.20031217 ETH | ||||
5024106 | 2468 days ago | 0.15044047 ETH | ||||
5021052 | 2468 days ago | 0.50877004 ETH | ||||
5020111 | 2468 days ago | 0.1 ETH | ||||
5020070 | 2468 days ago | 0.1 ETH | ||||
5020002 | 2468 days ago | 0.1 ETH | ||||
5018370 | 2469 days ago | 0.75880899 ETH | ||||
5018189 | 2469 days ago | 0.76726995 ETH | ||||
5016353 | 2469 days ago | 0.20217054 ETH | ||||
5015052 | 2469 days ago | 0.04497373 ETH | ||||
5011143 | 2470 days ago | 0.50592361 ETH | ||||
5011059 | 2470 days ago | 0.1 ETH | ||||
5010987 | 2470 days ago | 0.3 ETH | ||||
5010928 | 2470 days ago | 0.01 ETH |
Loading...
Loading
Contract Name:
KyberReserve
Compiler Version
v0.4.18+commit.9cf6e910
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2018-01-19 */ pragma solidity 0.4.18; interface SanityRatesInterface { function getSanityRate(ERC20 src, ERC20 dest) public view returns(uint); } contract PermissionGroups { address public admin; address public pendingAdmin; mapping(address=>bool) internal operators; mapping(address=>bool) internal alerters; address[] internal operatorsGroup; address[] internal alertersGroup; function PermissionGroups() public { admin = msg.sender; } modifier onlyAdmin() { require(msg.sender == admin); _; } modifier onlyOperator() { require(operators[msg.sender]); _; } modifier onlyAlerter() { require(alerters[msg.sender]); _; } function getOperators () external view returns(address[]) { return operatorsGroup; } function getAlerters () external view returns(address[]) { return alertersGroup; } event TransferAdminPending(address pendingAdmin); /** * @dev Allows the current admin to set the pendingAdmin address. * @param newAdmin The address to transfer ownership to. */ function transferAdmin(address newAdmin) public onlyAdmin { require(newAdmin != address(0)); TransferAdminPending(pendingAdmin); pendingAdmin = newAdmin; } event AdminClaimed( address newAdmin, address previousAdmin); /** * @dev Allows the pendingAdmin address to finalize the change admin process. */ function claimAdmin() public { require(pendingAdmin == msg.sender); AdminClaimed(pendingAdmin, admin); admin = pendingAdmin; pendingAdmin = address(0); } event AlerterAdded (address newAlerter, bool isAdd); function addAlerter(address newAlerter) public onlyAdmin { require(!alerters[newAlerter]); // prevent duplicates. AlerterAdded(newAlerter, true); alerters[newAlerter] = true; alertersGroup.push(newAlerter); } function removeAlerter (address alerter) public onlyAdmin { require(alerters[alerter]); alerters[alerter] = false; for (uint i = 0; i < alertersGroup.length; ++i) { if (alertersGroup[i] == alerter) { alertersGroup[i] = alertersGroup[alertersGroup.length - 1]; alertersGroup.length--; AlerterAdded(alerter, false); break; } } } event OperatorAdded(address newOperator, bool isAdd); function addOperator(address newOperator) public onlyAdmin { require(!operators[newOperator]); // prevent duplicates. OperatorAdded(newOperator, true); operators[newOperator] = true; operatorsGroup.push(newOperator); } function removeOperator (address operator) public onlyAdmin { require(operators[operator]); operators[operator] = false; for (uint i = 0; i < operatorsGroup.length; ++i) { if (operatorsGroup[i] == operator) { operatorsGroup[i] = operatorsGroup[operatorsGroup.length - 1]; operatorsGroup.length -= 1; OperatorAdded(operator, false); break; } } } } contract Withdrawable is PermissionGroups { event TokenWithdraw(ERC20 token, uint amount, address sendTo); /** * @dev Withdraw all ERC20 compatible tokens * @param token ERC20 The address of the token contract */ function withdrawToken(ERC20 token, uint amount, address sendTo) external onlyAdmin { require(token.transfer(sendTo, amount)); TokenWithdraw(token, amount, sendTo); } event EtherWithdraw(uint amount, address sendTo); /** * @dev Withdraw Ethers */ function withdrawEther(uint amount, address sendTo) external onlyAdmin { sendTo.transfer(amount); EtherWithdraw(amount, sendTo); } } contract VolumeImbalanceRecorder is Withdrawable { uint constant internal SLIDING_WINDOW_SIZE = 5; uint constant internal POW_2_64 = 2 ** 64; struct TokenControlInfo { uint minimalRecordResolution; // can be roughly 1 cent uint maxPerBlockImbalance; // in twei resolution uint maxTotalImbalance; // max total imbalance (between rate updates) // before halting trade } mapping(address => TokenControlInfo) internal tokenControlInfo; struct TokenImbalanceData { int lastBlockBuyUnitsImbalance; uint lastBlock; int totalBuyUnitsImbalance; uint lastRateUpdateBlock; } mapping(address => mapping(uint=>uint)) public tokenImbalanceData; function VolumeImbalanceRecorder(address _admin) public { require(_admin != address(0)); admin = _admin; } function setTokenControlInfo( ERC20 token, uint minimalRecordResolution, uint maxPerBlockImbalance, uint maxTotalImbalance ) public onlyAdmin { tokenControlInfo[token] = TokenControlInfo( minimalRecordResolution, maxPerBlockImbalance, maxTotalImbalance ); } function getTokenControlInfo(ERC20 token) public view returns(uint, uint, uint) { return (tokenControlInfo[token].minimalRecordResolution, tokenControlInfo[token].maxPerBlockImbalance, tokenControlInfo[token].maxTotalImbalance); } function addImbalance( ERC20 token, int buyAmount, uint rateUpdateBlock, uint currentBlock ) internal { uint currentBlockIndex = currentBlock % SLIDING_WINDOW_SIZE; int recordedBuyAmount = int(buyAmount / int(tokenControlInfo[token].minimalRecordResolution)); int prevImbalance = 0; TokenImbalanceData memory currentBlockData = decodeTokenImbalanceData(tokenImbalanceData[token][currentBlockIndex]); // first scenario - this is not the first tx in the current block if (currentBlockData.lastBlock == currentBlock) { if (uint(currentBlockData.lastRateUpdateBlock) == rateUpdateBlock) { // just increase imbalance currentBlockData.lastBlockBuyUnitsImbalance += recordedBuyAmount; currentBlockData.totalBuyUnitsImbalance += recordedBuyAmount; } else { // imbalance was changed in the middle of the block prevImbalance = getImbalanceInRange(token, rateUpdateBlock, currentBlock); currentBlockData.totalBuyUnitsImbalance = int(prevImbalance) + recordedBuyAmount; currentBlockData.lastBlockBuyUnitsImbalance += recordedBuyAmount; currentBlockData.lastRateUpdateBlock = uint(rateUpdateBlock); } } else { // first tx in the current block int currentBlockImbalance; (prevImbalance, currentBlockImbalance) = getImbalanceSinceRateUpdate(token, rateUpdateBlock, currentBlock); currentBlockData.lastBlockBuyUnitsImbalance = recordedBuyAmount; currentBlockData.lastBlock = uint(currentBlock); currentBlockData.lastRateUpdateBlock = uint(rateUpdateBlock); currentBlockData.totalBuyUnitsImbalance = int(prevImbalance) + recordedBuyAmount; } tokenImbalanceData[token][currentBlockIndex] = encodeTokenImbalanceData(currentBlockData); } function setGarbageToVolumeRecorder(ERC20 token) internal { for (uint i = 0; i < SLIDING_WINDOW_SIZE; i++) { tokenImbalanceData[token][i] = 0x1; } } function getImbalanceInRange(ERC20 token, uint startBlock, uint endBlock) internal view returns(int buyImbalance) { // check the imbalance in the sliding window require(startBlock <= endBlock); buyImbalance = 0; for (uint windowInd = 0; windowInd < SLIDING_WINDOW_SIZE; windowInd++) { TokenImbalanceData memory perBlockData = decodeTokenImbalanceData(tokenImbalanceData[token][windowInd]); if (perBlockData.lastBlock <= endBlock && perBlockData.lastBlock >= startBlock) { buyImbalance += int(perBlockData.lastBlockBuyUnitsImbalance); } } } function getImbalanceSinceRateUpdate(ERC20 token, uint rateUpdateBlock, uint currentBlock) internal view returns(int buyImbalance, int currentBlockImbalance) { buyImbalance = 0; currentBlockImbalance = 0; uint latestBlock = 0; int imbalanceInRange = 0; uint startBlock = rateUpdateBlock; uint endBlock = currentBlock; for (uint windowInd = 0; windowInd < SLIDING_WINDOW_SIZE; windowInd++) { TokenImbalanceData memory perBlockData = decodeTokenImbalanceData(tokenImbalanceData[token][windowInd]); if (perBlockData.lastBlock <= endBlock && perBlockData.lastBlock >= startBlock) { imbalanceInRange += perBlockData.lastBlockBuyUnitsImbalance; } if (perBlockData.lastRateUpdateBlock != rateUpdateBlock) continue; if (perBlockData.lastBlock < latestBlock) continue; latestBlock = perBlockData.lastBlock; buyImbalance = perBlockData.totalBuyUnitsImbalance; if (uint(perBlockData.lastBlock) == currentBlock) { currentBlockImbalance = perBlockData.lastBlockBuyUnitsImbalance; } } if (buyImbalance == 0) { buyImbalance = imbalanceInRange; } } function getImbalance(ERC20 token, uint rateUpdateBlock, uint currentBlock) internal view returns(int totalImbalance, int currentBlockImbalance) { int resolution = int(tokenControlInfo[token].minimalRecordResolution); (totalImbalance, currentBlockImbalance) = getImbalanceSinceRateUpdate( token, rateUpdateBlock, currentBlock); totalImbalance *= resolution; currentBlockImbalance *= resolution; } function getMaxPerBlockImbalance(ERC20 token) internal view returns(uint) { return tokenControlInfo[token].maxPerBlockImbalance; } function getMaxTotalImbalance(ERC20 token) internal view returns(uint) { return tokenControlInfo[token].maxTotalImbalance; } function encodeTokenImbalanceData(TokenImbalanceData data) internal pure returns(uint) { // check for overflows require(data.lastBlockBuyUnitsImbalance < int(POW_2_64 / 2)); require(data.lastBlockBuyUnitsImbalance > int(-1 * int(POW_2_64) / 2)); require(data.lastBlock < POW_2_64); require(data.totalBuyUnitsImbalance < int(POW_2_64 / 2)); require(data.totalBuyUnitsImbalance > int(-1 * int(POW_2_64) / 2)); require(data.lastRateUpdateBlock < POW_2_64); // do encoding uint result = uint(data.lastBlockBuyUnitsImbalance) & (POW_2_64 - 1); result |= data.lastBlock * POW_2_64; result |= (uint(data.totalBuyUnitsImbalance) & (POW_2_64 - 1)) * POW_2_64 * POW_2_64; result |= data.lastRateUpdateBlock * POW_2_64 * POW_2_64 * POW_2_64; return result; } function decodeTokenImbalanceData(uint input) internal pure returns(TokenImbalanceData) { TokenImbalanceData memory data; data.lastBlockBuyUnitsImbalance = int(int64(input & (POW_2_64 - 1))); data.lastBlock = uint(uint64((input / POW_2_64) & (POW_2_64 - 1))); data.totalBuyUnitsImbalance = int(int64((input / (POW_2_64 * POW_2_64)) & (POW_2_64 - 1))); data.lastRateUpdateBlock = uint(uint64((input / (POW_2_64 * POW_2_64 * POW_2_64)))); return data; } } contract Utils { ERC20 constant internal ETH_TOKEN_ADDRESS = ERC20(0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee); uint constant internal PRECISION = (10**18); uint constant internal MAX_QTY = (10**28); // 1B tokens uint constant internal MAX_RATE = (PRECISION * 10**6); // up to 1M tokens per ETH uint constant internal MAX_DECIMALS = 18; function calcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) { if (dstDecimals >= srcDecimals) { require((dstDecimals - srcDecimals) <= MAX_DECIMALS); return (srcQty * rate * (10**(dstDecimals - srcDecimals))) / PRECISION; } else { require((srcDecimals - dstDecimals) <= MAX_DECIMALS); return (srcQty * rate) / (PRECISION * (10**(srcDecimals - dstDecimals))); } } function calcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) { //source quantity is rounded up. to avoid dest quantity being too low. uint numerator; uint denominator; if (srcDecimals >= dstDecimals) { require((srcDecimals - dstDecimals) <= MAX_DECIMALS); numerator = (PRECISION * dstQty * (10**(srcDecimals - dstDecimals))); denominator = rate; } else { require((dstDecimals - srcDecimals) <= MAX_DECIMALS); numerator = (PRECISION * dstQty); denominator = (rate * (10**(dstDecimals - srcDecimals))); } return (numerator + denominator - 1) / denominator; //avoid rounding down errors } } contract ConversionRates is VolumeImbalanceRecorder, Utils { // bps - basic rate steps. one step is 1 / 10000 of the rate. struct StepFunction { int[] x; // quantity for each step. Quantity of each step includes previous steps. int[] y; // rate change per quantity step in bps. } struct TokenData { bool listed; // was added to reserve bool enabled; // whether trade is enabled // position in the compact data uint compactDataArrayIndex; uint compactDataFieldIndex; // rate data. base and changes according to quantity and reserve balance. // generally speaking. Sell rate is 1 / buy rate i.e. the buy in the other direction. uint baseBuyRate; // in PRECISION units. see KyberConstants uint baseSellRate; // PRECISION units. without (sell / buy) spread it is 1 / baseBuyRate StepFunction buyRateQtyStepFunction; // in bps. higher quantity - bigger the rate. StepFunction sellRateQtyStepFunction;// in bps. higher the qua StepFunction buyRateImbalanceStepFunction; // in BPS. higher reserve imbalance - bigger the rate. StepFunction sellRateImbalanceStepFunction; } /* this is the data for tokenRatesCompactData but solidity compiler optimizer is sub-optimal, and cannot write this structure in a single storage write so we represent it as bytes32 and do the byte tricks ourselves. struct TokenRatesCompactData { bytes14 buy; // change buy rate of token from baseBuyRate in 10 bps bytes14 sell; // change sell rate of token from baseSellRate in 10 bps uint32 blockNumber; } */ uint public validRateDurationInBlocks = 10; // rates are valid for this amount of blocks ERC20[] internal listedTokens; mapping(address=>TokenData) internal tokenData; bytes32[] internal tokenRatesCompactData; uint public numTokensInCurrentCompactData = 0; address public reserveContract; uint constant internal NUM_TOKENS_IN_COMPACT_DATA = 14; uint constant internal BYTES_14_OFFSET = (2 ** (8 * NUM_TOKENS_IN_COMPACT_DATA)); function ConversionRates(address _admin) public VolumeImbalanceRecorder(_admin) { } // solhint-disable-line no-empty-blocks function addToken(ERC20 token) public onlyAdmin { require(!tokenData[token].listed); tokenData[token].listed = true; listedTokens.push(token); if (numTokensInCurrentCompactData == 0) { tokenRatesCompactData.length++; // add new structure } tokenData[token].compactDataArrayIndex = tokenRatesCompactData.length - 1; tokenData[token].compactDataFieldIndex = numTokensInCurrentCompactData; numTokensInCurrentCompactData = (numTokensInCurrentCompactData + 1) % NUM_TOKENS_IN_COMPACT_DATA; setGarbageToVolumeRecorder(token); } function setCompactData(bytes14[] buy, bytes14[] sell, uint blockNumber, uint[] indices) public onlyOperator { require(buy.length == sell.length); require(indices.length == buy.length); require(blockNumber <= 0xFFFFFFFF); uint bytes14Offset = BYTES_14_OFFSET; for (uint i = 0; i < indices.length; i++) { require(indices[i] < tokenRatesCompactData.length); uint data = uint(buy[i]) | uint(sell[i]) * bytes14Offset | (blockNumber * (bytes14Offset * bytes14Offset)); tokenRatesCompactData[indices[i]] = bytes32(data); } } function setBaseRate( ERC20[] tokens, uint[] baseBuy, uint[] baseSell, bytes14[] buy, bytes14[] sell, uint blockNumber, uint[] indices ) public onlyOperator { require(tokens.length == baseBuy.length); require(tokens.length == baseSell.length); require(sell.length == buy.length); require(sell.length == indices.length); for (uint ind = 0; ind < tokens.length; ind++) { require(tokenData[tokens[ind]].listed); tokenData[tokens[ind]].baseBuyRate = baseBuy[ind]; tokenData[tokens[ind]].baseSellRate = baseSell[ind]; } setCompactData(buy, sell, blockNumber, indices); } function setQtyStepFunction( ERC20 token, int[] xBuy, int[] yBuy, int[] xSell, int[] ySell ) public onlyOperator { require(xBuy.length == yBuy.length); require(xSell.length == ySell.length); require(tokenData[token].listed); tokenData[token].buyRateQtyStepFunction = StepFunction(xBuy, yBuy); tokenData[token].sellRateQtyStepFunction = StepFunction(xSell, ySell); } function setImbalanceStepFunction( ERC20 token, int[] xBuy, int[] yBuy, int[] xSell, int[] ySell ) public onlyOperator { require(xBuy.length == yBuy.length); require(xSell.length == ySell.length); require(tokenData[token].listed); tokenData[token].buyRateImbalanceStepFunction = StepFunction(xBuy, yBuy); tokenData[token].sellRateImbalanceStepFunction = StepFunction(xSell, ySell); } function setValidRateDurationInBlocks(uint duration) public onlyAdmin { validRateDurationInBlocks = duration; } function enableTokenTrade(ERC20 token) public onlyAdmin { require(tokenData[token].listed); require(tokenControlInfo[token].minimalRecordResolution != 0); tokenData[token].enabled = true; } function disableTokenTrade(ERC20 token) public onlyAlerter { require(tokenData[token].listed); tokenData[token].enabled = false; } function setReserveAddress(address reserve) public onlyAdmin { reserveContract = reserve; } function recordImbalance( ERC20 token, int buyAmount, uint rateUpdateBlock, uint currentBlock ) public { require(msg.sender == reserveContract); if (rateUpdateBlock == 0) rateUpdateBlock = getRateUpdateBlock(token); return addImbalance(token, buyAmount, rateUpdateBlock, currentBlock); } /* solhint-disable function-max-lines */ function getRate(ERC20 token, uint currentBlockNumber, bool buy, uint qty) public view returns(uint) { // check if trade is enabled if (!tokenData[token].enabled) return 0; if (tokenControlInfo[token].minimalRecordResolution == 0) return 0; // token control info not set // get rate update block bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; uint updateRateBlock = getLast4Bytes(compactData); if (currentBlockNumber >= updateRateBlock + validRateDurationInBlocks) return 0; // rate is expired // check imbalance int totalImbalance; int blockImbalance; (totalImbalance, blockImbalance) = getImbalance(token, updateRateBlock, currentBlockNumber); // calculate actual rate int imbalanceQty; int extraBps; int8 rateUpdate; uint rate; if (buy) { // start with base rate rate = tokenData[token].baseBuyRate; // add rate update rateUpdate = getRateByteFromCompactData(compactData, token, true); extraBps = int(rateUpdate) * 10; rate = addBps(rate, extraBps); // compute token qty qty = getTokenQty(token, rate, qty); imbalanceQty = int(qty); totalImbalance += imbalanceQty; // add qty overhead extraBps = executeStepFunction(tokenData[token].buyRateQtyStepFunction, int(qty)); rate = addBps(rate, extraBps); // add imbalance overhead extraBps = executeStepFunction(tokenData[token].buyRateImbalanceStepFunction, totalImbalance); rate = addBps(rate, extraBps); } else { // start with base rate rate = tokenData[token].baseSellRate; // add rate update rateUpdate = getRateByteFromCompactData(compactData, token, false); extraBps = int(rateUpdate) * 10; rate = addBps(rate, extraBps); // compute token qty imbalanceQty = -1 * int(qty); totalImbalance += imbalanceQty; // add qty overhead extraBps = executeStepFunction(tokenData[token].sellRateQtyStepFunction, int(qty)); rate = addBps(rate, extraBps); // add imbalance overhead extraBps = executeStepFunction(tokenData[token].sellRateImbalanceStepFunction, totalImbalance); rate = addBps(rate, extraBps); } if (abs(totalImbalance + imbalanceQty) >= getMaxTotalImbalance(token)) return 0; if (abs(blockImbalance + imbalanceQty) >= getMaxPerBlockImbalance(token)) return 0; return rate; } /* solhint-enable function-max-lines */ function getBasicRate(ERC20 token, bool buy) public view returns(uint) { if (buy) return tokenData[token].baseBuyRate; else return tokenData[token].baseSellRate; } function getCompactData(ERC20 token) public view returns(uint, uint, byte, byte) { uint arrayIndex = tokenData[token].compactDataArrayIndex; uint fieldOffset = tokenData[token].compactDataFieldIndex; return ( arrayIndex, fieldOffset, byte(getRateByteFromCompactData(tokenRatesCompactData[arrayIndex], token, true)), byte(getRateByteFromCompactData(tokenRatesCompactData[arrayIndex], token, false)) ); } function getTokenBasicData(ERC20 token) public view returns(bool, bool) { return (tokenData[token].listed, tokenData[token].enabled); } /* solhint-disable code-complexity */ function getStepFunctionData(ERC20 token, uint command, uint param) public view returns(int) { if (command == 0) return int(tokenData[token].buyRateQtyStepFunction.x.length); if (command == 1) return tokenData[token].buyRateQtyStepFunction.x[param]; if (command == 2) return int(tokenData[token].buyRateQtyStepFunction.y.length); if (command == 3) return tokenData[token].buyRateQtyStepFunction.y[param]; if (command == 4) return int(tokenData[token].sellRateQtyStepFunction.x.length); if (command == 5) return tokenData[token].sellRateQtyStepFunction.x[param]; if (command == 6) return int(tokenData[token].sellRateQtyStepFunction.y.length); if (command == 7) return tokenData[token].sellRateQtyStepFunction.y[param]; if (command == 8) return int(tokenData[token].buyRateImbalanceStepFunction.x.length); if (command == 9) return tokenData[token].buyRateImbalanceStepFunction.x[param]; if (command == 10) return int(tokenData[token].buyRateImbalanceStepFunction.y.length); if (command == 11) return tokenData[token].buyRateImbalanceStepFunction.y[param]; if (command == 12) return int(tokenData[token].sellRateImbalanceStepFunction.x.length); if (command == 13) return tokenData[token].sellRateImbalanceStepFunction.x[param]; if (command == 14) return int(tokenData[token].sellRateImbalanceStepFunction.y.length); if (command == 15) return tokenData[token].sellRateImbalanceStepFunction.y[param]; revert(); } /* solhint-enable code-complexity */ function getRateUpdateBlock(ERC20 token) public view returns(uint) { bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; return getLast4Bytes(compactData); } function getListedTokens() public view returns(ERC20[]) { return listedTokens; } function getTokenQty(ERC20 token, uint ethQty, uint rate) internal view returns(uint) { uint dstDecimals = token.decimals(); uint srcDecimals = 18; return calcDstQty(ethQty, srcDecimals, dstDecimals, rate); } function getLast4Bytes(bytes32 b) internal pure returns(uint) { // cannot trust compiler with not turning bit operations into EXP opcode return uint(b) / (BYTES_14_OFFSET * BYTES_14_OFFSET); } function getRateByteFromCompactData(bytes32 data, ERC20 token, bool buy) internal view returns(int8) { uint fieldOffset = tokenData[token].compactDataFieldIndex; uint byteOffset; if (buy) byteOffset = 32 - NUM_TOKENS_IN_COMPACT_DATA + fieldOffset; else byteOffset = 4 + fieldOffset; return int8(data[byteOffset]); } function executeStepFunction(StepFunction f, int x) internal pure returns(int) { uint len = f.y.length; for (uint ind = 0; ind < len; ind++) { if (x <= f.x[ind]) return f.y[ind]; } return f.y[len-1]; } function addBps(uint rate, int bps) internal pure returns(uint) { uint maxBps = 100 * 100; return (rate * uint(int(maxBps) + bps)) / maxBps; } function abs(int x) internal pure returns(uint) { if (x < 0) return uint(-1 * x); else return uint(x); } } contract KyberReserve is Withdrawable, Utils { address public kyberNetwork; bool public tradeEnabled; ConversionRates public conversionRatesContract; SanityRatesInterface public sanityRatesContract; mapping(bytes32=>bool) public approvedWithdrawAddresses; // sha3(token,address)=>bool function KyberReserve(address _kyberNetwork, ConversionRates _ratesContract, address _admin) public { require(_admin != address(0)); require(_ratesContract != address(0)); require(_kyberNetwork != address(0)); kyberNetwork = _kyberNetwork; conversionRatesContract = _ratesContract; admin = _admin; tradeEnabled = true; } event DepositToken(ERC20 token, uint amount); function() public payable { DepositToken(ETH_TOKEN_ADDRESS, msg.value); } event TradeExecute( address indexed origin, address src, uint srcAmount, address destToken, uint destAmount, address destAddress ); function trade( ERC20 srcToken, uint srcAmount, ERC20 destToken, address destAddress, uint conversionRate, bool validate ) public payable returns(bool) { require(tradeEnabled); require(msg.sender == kyberNetwork); require(doTrade(srcToken, srcAmount, destToken, destAddress, conversionRate, validate)); return true; } event TradeEnabled(bool enable); function enableTrade() public onlyAdmin returns(bool) { tradeEnabled = true; TradeEnabled(true); return true; } function disableTrade() public onlyAlerter returns(bool) { tradeEnabled = false; TradeEnabled(false); return true; } event WithdrawAddressApproved(ERC20 token, address addr, bool approve); function approveWithdrawAddress(ERC20 token, address addr, bool approve) public onlyAdmin { approvedWithdrawAddresses[keccak256(token, addr)] = approve; WithdrawAddressApproved(token, addr, approve); } event WithdrawFunds(ERC20 token, uint amount, address destination); function withdraw(ERC20 token, uint amount, address destination) public onlyOperator returns(bool) { require(approvedWithdrawAddresses[keccak256(token, destination)]); if (token == ETH_TOKEN_ADDRESS) { destination.transfer(amount); } else { require(token.transfer(destination, amount)); } WithdrawFunds(token, amount, destination); return true; } event SetContractAddresses(address network, address rate, address sanity); function setContracts(address _kyberNetwork, ConversionRates _conversionRates, SanityRatesInterface _sanityRates) public onlyAdmin { require(_kyberNetwork != address(0)); require(_conversionRates != address(0)); kyberNetwork = _kyberNetwork; conversionRatesContract = _conversionRates; sanityRatesContract = _sanityRates; SetContractAddresses(kyberNetwork, conversionRatesContract, sanityRatesContract); } //////////////////////////////////////////////////////////////////////////// /// status functions /////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// function getBalance(ERC20 token) public view returns(uint) { if (token == ETH_TOKEN_ADDRESS) return this.balance; else return token.balanceOf(this); } function getDecimals(ERC20 token) public view returns(uint) { if (token == ETH_TOKEN_ADDRESS) return 18; return token.decimals(); } function getDestQty(ERC20 src, ERC20 dest, uint srcQty, uint rate) public view returns(uint) { uint dstDecimals = getDecimals(dest); uint srcDecimals = getDecimals(src); return calcDstQty(srcQty, srcDecimals, dstDecimals, rate); } function getSrcQty(ERC20 src, ERC20 dest, uint dstQty, uint rate) public view returns(uint) { uint dstDecimals = getDecimals(dest); uint srcDecimals = getDecimals(src); return calcSrcQty(dstQty, srcDecimals, dstDecimals, rate); } function getConversionRate(ERC20 src, ERC20 dest, uint srcQty, uint blockNumber) public view returns(uint) { ERC20 token; bool buy; if (!tradeEnabled) return 0; if (ETH_TOKEN_ADDRESS == src) { buy = true; token = dest; } else if (ETH_TOKEN_ADDRESS == dest) { buy = false; token = src; } else { return 0; // pair is not listed } uint rate = conversionRatesContract.getRate(token, blockNumber, buy, srcQty); uint destQty = getDestQty(src, dest, srcQty, rate); if (getBalance(dest) < destQty) return 0; if (sanityRatesContract != address(0)) { uint sanityRate = sanityRatesContract.getSanityRate(src, dest); if (rate > sanityRate) return 0; } return rate; } /// @dev do a trade /// @param srcToken Src token /// @param srcAmount Amount of src token /// @param destToken Destination token /// @param destAddress Destination address to send tokens to /// @param validate If true, additional validations are applicable /// @return true iff trade is successful function doTrade( ERC20 srcToken, uint srcAmount, ERC20 destToken, address destAddress, uint conversionRate, bool validate ) internal returns(bool) { // can skip validation if done at kyber network level if (validate) { require(conversionRate > 0); if (srcToken == ETH_TOKEN_ADDRESS) require(msg.value == srcAmount); else require(msg.value == 0); } uint destAmount = getDestQty(srcToken, destToken, srcAmount, conversionRate); // sanity check require(destAmount > 0); // add to imbalance ERC20 token; int buy; if (srcToken == ETH_TOKEN_ADDRESS) { buy = int(destAmount); token = destToken; } else { buy = -1 * int(srcAmount); token = srcToken; } conversionRatesContract.recordImbalance( token, buy, 0, block.number ); // collect src tokens if (srcToken != ETH_TOKEN_ADDRESS) { require(srcToken.transferFrom(msg.sender, this, srcAmount)); } // send dest tokens if (destToken == ETH_TOKEN_ADDRESS) { destAddress.transfer(destAmount); } else { require(destToken.transfer(destAddress, destAmount)); } TradeExecute(msg.sender, srcToken, srcAmount, destToken, destAmount, destAddress); return true; } } interface ERC20 { function totalSupply() public view returns (uint supply); function balanceOf(address _owner) public view returns (uint balance); function transfer(address _to, uint _value) public returns (bool success); function transferFrom(address _from, address _to, uint _value) public returns (bool success); function approve(address _spender, uint _value) public returns (bool success); function allowance(address _owner, address _spender) public view returns (uint remaining); function decimals() public view returns(uint digits); event Approval(address indexed _owner, address indexed _spender, uint _value); } contract SanityRates is SanityRatesInterface, Withdrawable, Utils { mapping(address=>uint) public tokenRate; mapping(address=>uint) public reasonableDiffInBps; function SanityRates(address _admin) public { require(_admin != address(0)); admin = _admin; } function setReasonableDiff(ERC20[] srcs, uint[] diff) public onlyAdmin { require(srcs.length == diff.length); for (uint i = 0; i < srcs.length; i++) { reasonableDiffInBps[srcs[i]] = diff[i]; } } function setSanityRates(ERC20[] srcs, uint[] rates) public onlyOperator { require(srcs.length == rates.length); for (uint i = 0; i < srcs.length; i++) { tokenRate[srcs[i]] = rates[i]; } } function getSanityRate(ERC20 src, ERC20 dest) public view returns(uint) { if (src != ETH_TOKEN_ADDRESS && dest != ETH_TOKEN_ADDRESS) return 0; uint rate; address token; if (src == ETH_TOKEN_ADDRESS) { rate = (PRECISION*PRECISION)/tokenRate[dest]; token = dest; } else { rate = tokenRate[src]; token = src; } return rate * (10000 + reasonableDiffInBps[token])/10000; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[],"name":"enableTrade","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"alerter","type":"address"}],"name":"removeAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"},{"name":"sendTo","type":"address"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAlerter","type":"address"}],"name":"addAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"sanityRatesContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"addr","type":"address"},{"name":"approve","type":"bool"}],"name":"approveWithdrawAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"},{"name":"destination","type":"address"}],"name":"withdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"disableTrade","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"srcToken","type":"address"},{"name":"srcAmount","type":"uint256"},{"name":"destToken","type":"address"},{"name":"destAddress","type":"address"},{"name":"conversionRate","type":"uint256"},{"name":"validate","type":"bool"}],"name":"trade","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAlerters","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"dest","type":"address"},{"name":"srcQty","type":"uint256"},{"name":"blockNumber","type":"uint256"}],"name":"getConversionRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOperator","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"dest","type":"address"},{"name":"dstQty","type":"uint256"},{"name":"rate","type":"uint256"}],"name":"getSrcQty","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_kyberNetwork","type":"address"},{"name":"_conversionRates","type":"address"},{"name":"_sanityRates","type":"address"}],"name":"setContracts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kyberNetwork","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"sendTo","type":"address"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getDecimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"conversionRatesContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tradeEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"approvedWithdrawAddresses","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"dest","type":"address"},{"name":"srcQty","type":"uint256"},{"name":"rate","type":"uint256"}],"name":"getDestQty","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_kyberNetwork","type":"address"},{"name":"_ratesContract","type":"address"},{"name":"_admin","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"DepositToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"origin","type":"address"},{"indexed":false,"name":"src","type":"address"},{"indexed":false,"name":"srcAmount","type":"uint256"},{"indexed":false,"name":"destToken","type":"address"},{"indexed":false,"name":"destAmount","type":"uint256"},{"indexed":false,"name":"destAddress","type":"address"}],"name":"TradeExecute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"enable","type":"bool"}],"name":"TradeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"addr","type":"address"},{"indexed":false,"name":"approve","type":"bool"}],"name":"WithdrawAddressApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"destination","type":"address"}],"name":"WithdrawFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"network","type":"address"},{"indexed":false,"name":"rate","type":"address"},{"indexed":false,"name":"sanity","type":"address"}],"name":"SetContractAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"TokenWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"EtherWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pendingAdmin","type":"address"}],"name":"TransferAdminPending","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAdmin","type":"address"},{"indexed":false,"name":"previousAdmin","type":"address"}],"name":"AdminClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAlerter","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"AlerterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOperator","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"OperatorAdded","type":"event"}]
Contract Creation Code
606060405234156200001057600080fd5b604051606080620035f783398101604052808051906020019091908051906020019091908051906020019091905050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515620000bc57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515620000f957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156200013657600080fd5b82600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600660146101000a81548160ff0219169083151502179055505050506133d180620002266000396000f300606060405260043610610169576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806299d386146101ea57806301a12fd314610217578063267822471461025057806327a099d8146102a55780633ccdbb281461030f578063408ee7fe1461037057806347e6924f146103a9578063546dc71c146103fe57806369328dec146104615780636940030f146104da5780636cf698111461050757806375829def146105a857806377f50f97146105e15780637c423f54146105f65780637cd44272146106605780639870d7fe146106de578063a7fca95314610717578063ac8a584a14610795578063b3066d49146107ce578063b78b842d14610845578063ce56c4541461089a578063cf54aaa0146108dc578063d5847d3314610929578063d621e8131461097e578063d7b7024d146109ab578063f851a440146109ea578063f8b2cb4f14610a3f578063fa64dffa14610a8c575b7f2d0c0a8842b9944ece1495eb61121621b5e36bd6af3bba0318c695f525aef79f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1005b34156101f557600080fd5b6101fd610b0a565b604051808215151515815260200191505060405180910390f35b341561022257600080fd5b61024e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bc5565b005b341561025b57600080fd5b610263610e87565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156102b057600080fd5b6102b8610ead565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102fb5780820151818401526020810190506102e0565b505050509050019250505060405180910390f35b341561031a57600080fd5b61036e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610f41565b005b341561037b57600080fd5b6103a7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611111565b005b34156103b457600080fd5b6103bc6112f3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561040957600080fd5b61045f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080351515906020019091905050611319565b005b341561046c57600080fd5b6104c0600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114e2565b604051808215151515815260200191505060405180910390f35b34156104e557600080fd5b6104ed61180c565b604051808215151515815260200191505060405180910390f35b61058e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803515159060200190919050506118c4565b604051808215151515815260200191505060405180910390f35b34156105b357600080fd5b6105df600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611964565b005b34156105ec57600080fd5b6105f4611ac4565b005b341561060157600080fd5b610609611ca0565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561064c578082015181840152602081019050610631565b505050509050019250505060405180910390f35b341561066b57600080fd5b6106c8600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091908035906020019091905050611d34565b6040518082815260200191505060405180910390f35b34156106e957600080fd5b610715600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506120c4565b005b341561072257600080fd5b61077f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919080359060200190919050506122a6565b6040518082815260200191505060405180910390f35b34156107a057600080fd5b6107cc600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506122d9565b005b34156107d957600080fd5b610843600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061259e565b005b341561085057600080fd5b61085861286a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108a557600080fd5b6108da600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612890565b005b34156108e757600080fd5b610913600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061299a565b6040518082815260200191505060405180910390f35b341561093457600080fd5b61093c612a7c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561098957600080fd5b610991612aa2565b604051808215151515815260200191505060405180910390f35b34156109b657600080fd5b6109d0600480803560001916906020019091905050612ab5565b604051808215151515815260200191505060405180910390f35b34156109f557600080fd5b6109fd612ad5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3415610a4a57600080fd5b610a76600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612afa565b6040518082815260200191505060405180910390f35b3415610a9757600080fd5b610af4600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091908035906020019091905050612c29565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b6757600080fd5b6001600660146101000a81548160ff0219169083151502179055507f7d7f00509dd73ac4449f698ae75ccc797895eff5fa9d446d3df387598a26e7356001604051808215151515815260200191505060405180910390a16001905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c2257600080fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c7a57600080fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b600580549050811015610e83578173ffffffffffffffffffffffffffffffffffffffff16600582815481101515610d0a57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610e78576005600160058054905003815481101515610d6957fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600582815481101515610da457fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506005805480919060019003610e029190613314565b507f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762826000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a1610e83565b806001019050610cd7565b5050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610eb5613340565b6004805480602002602001604051908101604052809291908181526020018280548015610f3757602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610eed575b5050505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610f9c57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb82846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561104757600080fd5b6102c65a03f1151561105857600080fd5b50505060405180519050151561106d57600080fd5b7f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e6838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561116c57600080fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156111c557600080fd5b7f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762816001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600580548060010182816112a19190613354565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561137457600080fd5b80600960008585604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390206000191660001916815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd5fd5351efae1f4bb760079da9f0ff9589e2c3e216337ca9d39cdff573b245c4838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182151515158152602001935050505060405180910390a1505050565b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561153c57600080fd5b600960008584604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390206000191660001916815260200190815260200160002060009054906101000a900460ff16151561160357600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611690578173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050151561168b57600080fd5b611762565b8373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561173b57600080fd5b6102c65a03f1151561174c57600080fd5b50505060405180519050151561176157600080fd5b5b7fb67719fc33c1f17d31bf3a698690d62066b1e0bae28fcd3c56cf2c015c2863d6848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1600190509392505050565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561186657600080fd5b6000600660146101000a81548160ff0219169083151502179055507f7d7f00509dd73ac4449f698ae75ccc797895eff5fa9d446d3df387598a26e7356000604051808215151515815260200191505060405180910390a16001905090565b6000600660149054906101000a900460ff1615156118e157600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561193d57600080fd5b61194b878787878787612c5c565b151561195657600080fd5b600190509695505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156119bf57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156119fb57600080fd5b7f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc40600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611b2057600080fd5b7f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b611ca8613340565b6005805480602002602001604051908101604052809291908181526020018280548015611d2a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611ce0575b5050505050905090565b600080600080600080600660149054906101000a900460ff161515611d5c57600095506120b7565b8973ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff161415611db05760019350889450611e0e565b8873ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff161415611e045760009350899450611e0d565b600095506120b7565b5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b8e9c22e8689878c6000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183151515158152602001828152602001945050505050602060405180830381600087803b1515611eef57600080fd5b6102c65a03f11515611f0057600080fd5b505050604051805190509250611f188a8a8a86612c29565b915081611f248a612afa565b1015611f3357600095506120b7565b600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120b357600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a58092b78b8b6000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b151561208457600080fd5b6102c65a03f1151561209557600080fd5b505050604051805190509050808311156120b257600095506120b7565b5b8295505b5050505050949350505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561211f57600080fd5b600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561217857600080fd5b7f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b816001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600480548060010182816122549190613354565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60008060006122b48661299a565b91506122bf8761299a565b90506122cd85828487613216565b92505050949350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561233657600080fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561238e57600080fd5b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b60048054905081101561259a578173ffffffffffffffffffffffffffffffffffffffff1660048281548110151561241e57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561258f57600460016004805490500381548110151561247d57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166004828154811015156124b857fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016004818180549050039150816125199190613314565b507f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b826000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a161259a565b8060010190506123eb565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156125f957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561263557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561267157600080fd5b82600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7a85322644a4462d8ff5482d2a841a4d231f8cfb3c9f4a50f66f8b2bd568c31c600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156128eb57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050151561292b57600080fd5b7fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de8282604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156129ed5760129050612a77565b8173ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515612a5957600080fd5b6102c65a03f11515612a6a57600080fd5b5050506040518051905090505b919050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660149054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b63573073ffffffffffffffffffffffffffffffffffffffff16319050612c24565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515612c0657600080fd5b6102c65a03f11515612c1757600080fd5b5050506040518051905090505b919050565b6000806000612c378661299a565b9150612c428761299a565b9050612c5085828487613299565b92505050949350505050565b6000806000808415612ce357600086111515612c7757600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415612cd2578834141515612ccd57600080fd5b612ce2565b600034141515612ce157600080fd5b5b5b612cef8a898b89612c29565b9250600083111515612d0057600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415612d5357829050879150612d7c565b887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0290508991505b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c6fd210383836000436040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152602001828152602001945050505050600060405180830381600087803b1515612e5157600080fd5b6102c65a03f11515612e6257600080fd5b50505073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16141515612fb4578973ffffffffffffffffffffffffffffffffffffffff166323b872dd33308c6000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515612f8d57600080fd5b6102c65a03f11515612f9e57600080fd5b505050604051805190501515612fb357600080fd5b5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415613041578673ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050151561303c57600080fd5b613113565b8773ffffffffffffffffffffffffffffffffffffffff1663a9059cbb88856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156130ec57600080fd5b6102c65a03f115156130fd57600080fd5b50505060405180519050151561311257600080fd5b5b3373ffffffffffffffffffffffffffffffffffffffff167fea9415385bae08fe9f6dc457b02577166790cde83bb18cc340aac6cb81b824de8b8b8b878c604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060405180910390a2600193505050509695505050505050565b600080600084861015156132525760128587031115151561323657600080fd5b848603600a0a87670de0b6b3a76400000202915083905061327c565b60128686031115151561326457600080fd5b86670de0b6b3a7640000029150858503600a0a840290505b8060018284010381151561328c57fe5b0492505050949350505050565b600083831015156132da576012848403111515156132b657600080fd5b670de0b6b3a7640000848403600a0a838702028115156132d257fe5b04905061330c565b6012838503111515156132ec57600080fd5b828403600a0a670de0b6b3a76400000282860281151561330857fe5b0490505b949350505050565b81548183558181151161333b5781836000526020600020918201910161333a9190613380565b5b505050565b602060405190810160405280600081525090565b81548183558181151161337b5781836000526020600020918201910161337a9190613380565b5b505050565b6133a291905b8082111561339e576000816000905550600101613386565b5090565b905600a165627a7a723058202d6c873b7b3337a5d038ea363fc051b5760cbd1050a2f84ec851f65aba9668f80029000000000000000000000000803e2b13a11c21ec0616cead4a3d2ebe1326f5b0000000000000000000000000d4af09f41c674141e9f8c1ce2883f08ecafd6649000000000000000000000000346fbe5d02c89fb4599f33bdce987981d573740a
Deployed Bytecode
0x606060405260043610610169576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806299d386146101ea57806301a12fd314610217578063267822471461025057806327a099d8146102a55780633ccdbb281461030f578063408ee7fe1461037057806347e6924f146103a9578063546dc71c146103fe57806369328dec146104615780636940030f146104da5780636cf698111461050757806375829def146105a857806377f50f97146105e15780637c423f54146105f65780637cd44272146106605780639870d7fe146106de578063a7fca95314610717578063ac8a584a14610795578063b3066d49146107ce578063b78b842d14610845578063ce56c4541461089a578063cf54aaa0146108dc578063d5847d3314610929578063d621e8131461097e578063d7b7024d146109ab578063f851a440146109ea578063f8b2cb4f14610a3f578063fa64dffa14610a8c575b7f2d0c0a8842b9944ece1495eb61121621b5e36bd6af3bba0318c695f525aef79f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1005b34156101f557600080fd5b6101fd610b0a565b604051808215151515815260200191505060405180910390f35b341561022257600080fd5b61024e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bc5565b005b341561025b57600080fd5b610263610e87565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156102b057600080fd5b6102b8610ead565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102fb5780820151818401526020810190506102e0565b505050509050019250505060405180910390f35b341561031a57600080fd5b61036e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610f41565b005b341561037b57600080fd5b6103a7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611111565b005b34156103b457600080fd5b6103bc6112f3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561040957600080fd5b61045f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080351515906020019091905050611319565b005b341561046c57600080fd5b6104c0600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114e2565b604051808215151515815260200191505060405180910390f35b34156104e557600080fd5b6104ed61180c565b604051808215151515815260200191505060405180910390f35b61058e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803515159060200190919050506118c4565b604051808215151515815260200191505060405180910390f35b34156105b357600080fd5b6105df600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611964565b005b34156105ec57600080fd5b6105f4611ac4565b005b341561060157600080fd5b610609611ca0565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561064c578082015181840152602081019050610631565b505050509050019250505060405180910390f35b341561066b57600080fd5b6106c8600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091908035906020019091905050611d34565b6040518082815260200191505060405180910390f35b34156106e957600080fd5b610715600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506120c4565b005b341561072257600080fd5b61077f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919080359060200190919050506122a6565b6040518082815260200191505060405180910390f35b34156107a057600080fd5b6107cc600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506122d9565b005b34156107d957600080fd5b610843600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061259e565b005b341561085057600080fd5b61085861286a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108a557600080fd5b6108da600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612890565b005b34156108e757600080fd5b610913600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061299a565b6040518082815260200191505060405180910390f35b341561093457600080fd5b61093c612a7c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561098957600080fd5b610991612aa2565b604051808215151515815260200191505060405180910390f35b34156109b657600080fd5b6109d0600480803560001916906020019091905050612ab5565b604051808215151515815260200191505060405180910390f35b34156109f557600080fd5b6109fd612ad5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3415610a4a57600080fd5b610a76600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612afa565b6040518082815260200191505060405180910390f35b3415610a9757600080fd5b610af4600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091908035906020019091905050612c29565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b6757600080fd5b6001600660146101000a81548160ff0219169083151502179055507f7d7f00509dd73ac4449f698ae75ccc797895eff5fa9d446d3df387598a26e7356001604051808215151515815260200191505060405180910390a16001905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c2257600080fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c7a57600080fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b600580549050811015610e83578173ffffffffffffffffffffffffffffffffffffffff16600582815481101515610d0a57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610e78576005600160058054905003815481101515610d6957fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600582815481101515610da457fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506005805480919060019003610e029190613314565b507f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762826000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a1610e83565b806001019050610cd7565b5050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610eb5613340565b6004805480602002602001604051908101604052809291908181526020018280548015610f3757602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610eed575b5050505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610f9c57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb82846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561104757600080fd5b6102c65a03f1151561105857600080fd5b50505060405180519050151561106d57600080fd5b7f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e6838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561116c57600080fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156111c557600080fd5b7f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762816001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600580548060010182816112a19190613354565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561137457600080fd5b80600960008585604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390206000191660001916815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd5fd5351efae1f4bb760079da9f0ff9589e2c3e216337ca9d39cdff573b245c4838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182151515158152602001935050505060405180910390a1505050565b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561153c57600080fd5b600960008584604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390206000191660001916815260200190815260200160002060009054906101000a900460ff16151561160357600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611690578173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050151561168b57600080fd5b611762565b8373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561173b57600080fd5b6102c65a03f1151561174c57600080fd5b50505060405180519050151561176157600080fd5b5b7fb67719fc33c1f17d31bf3a698690d62066b1e0bae28fcd3c56cf2c015c2863d6848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1600190509392505050565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561186657600080fd5b6000600660146101000a81548160ff0219169083151502179055507f7d7f00509dd73ac4449f698ae75ccc797895eff5fa9d446d3df387598a26e7356000604051808215151515815260200191505060405180910390a16001905090565b6000600660149054906101000a900460ff1615156118e157600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561193d57600080fd5b61194b878787878787612c5c565b151561195657600080fd5b600190509695505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156119bf57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156119fb57600080fd5b7f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc40600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611b2057600080fd5b7f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b611ca8613340565b6005805480602002602001604051908101604052809291908181526020018280548015611d2a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611ce0575b5050505050905090565b600080600080600080600660149054906101000a900460ff161515611d5c57600095506120b7565b8973ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff161415611db05760019350889450611e0e565b8873ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff161415611e045760009350899450611e0d565b600095506120b7565b5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b8e9c22e8689878c6000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183151515158152602001828152602001945050505050602060405180830381600087803b1515611eef57600080fd5b6102c65a03f11515611f0057600080fd5b505050604051805190509250611f188a8a8a86612c29565b915081611f248a612afa565b1015611f3357600095506120b7565b600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120b357600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a58092b78b8b6000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b151561208457600080fd5b6102c65a03f1151561209557600080fd5b505050604051805190509050808311156120b257600095506120b7565b5b8295505b5050505050949350505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561211f57600080fd5b600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561217857600080fd5b7f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b816001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600480548060010182816122549190613354565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60008060006122b48661299a565b91506122bf8761299a565b90506122cd85828487613216565b92505050949350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561233657600080fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561238e57600080fd5b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b60048054905081101561259a578173ffffffffffffffffffffffffffffffffffffffff1660048281548110151561241e57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561258f57600460016004805490500381548110151561247d57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166004828154811015156124b857fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016004818180549050039150816125199190613314565b507f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b826000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a161259a565b8060010190506123eb565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156125f957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561263557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561267157600080fd5b82600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7a85322644a4462d8ff5482d2a841a4d231f8cfb3c9f4a50f66f8b2bd568c31c600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156128eb57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050151561292b57600080fd5b7fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de8282604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156129ed5760129050612a77565b8173ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515612a5957600080fd5b6102c65a03f11515612a6a57600080fd5b5050506040518051905090505b919050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660149054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b63573073ffffffffffffffffffffffffffffffffffffffff16319050612c24565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515612c0657600080fd5b6102c65a03f11515612c1757600080fd5b5050506040518051905090505b919050565b6000806000612c378661299a565b9150612c428761299a565b9050612c5085828487613299565b92505050949350505050565b6000806000808415612ce357600086111515612c7757600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415612cd2578834141515612ccd57600080fd5b612ce2565b600034141515612ce157600080fd5b5b5b612cef8a898b89612c29565b9250600083111515612d0057600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415612d5357829050879150612d7c565b887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0290508991505b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c6fd210383836000436040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152602001828152602001945050505050600060405180830381600087803b1515612e5157600080fd5b6102c65a03f11515612e6257600080fd5b50505073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16141515612fb4578973ffffffffffffffffffffffffffffffffffffffff166323b872dd33308c6000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515612f8d57600080fd5b6102c65a03f11515612f9e57600080fd5b505050604051805190501515612fb357600080fd5b5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415613041578673ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050151561303c57600080fd5b613113565b8773ffffffffffffffffffffffffffffffffffffffff1663a9059cbb88856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156130ec57600080fd5b6102c65a03f115156130fd57600080fd5b50505060405180519050151561311257600080fd5b5b3373ffffffffffffffffffffffffffffffffffffffff167fea9415385bae08fe9f6dc457b02577166790cde83bb18cc340aac6cb81b824de8b8b8b878c604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060405180910390a2600193505050509695505050505050565b600080600084861015156132525760128587031115151561323657600080fd5b848603600a0a87670de0b6b3a76400000202915083905061327c565b60128686031115151561326457600080fd5b86670de0b6b3a7640000029150858503600a0a840290505b8060018284010381151561328c57fe5b0492505050949350505050565b600083831015156132da576012848403111515156132b657600080fd5b670de0b6b3a7640000848403600a0a838702028115156132d257fe5b04905061330c565b6012838503111515156132ec57600080fd5b828403600a0a670de0b6b3a76400000282860281151561330857fe5b0490505b949350505050565b81548183558181151161333b5781836000526020600020918201910161333a9190613380565b5b505050565b602060405190810160405280600081525090565b81548183558181151161337b5781836000526020600020918201910161337a9190613380565b5b505050565b6133a291905b8082111561339e576000816000905550600101613386565b5090565b905600a165627a7a723058202d6c873b7b3337a5d038ea363fc051b5760cbd1050a2f84ec851f65aba9668f80029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000803e2b13a11c21ec0616cead4a3d2ebe1326f5b0000000000000000000000000d4af09f41c674141e9f8c1ce2883f08ecafd6649000000000000000000000000346fbe5d02c89fb4599f33bdce987981d573740a
-----Decoded View---------------
Arg [0] : _kyberNetwork (address): 0x803e2b13a11c21Ec0616Cead4A3D2eBe1326f5B0
Arg [1] : _ratesContract (address): 0xd4AF09F41C674141e9F8c1ce2883F08ECAfd6649
Arg [2] : _admin (address): 0x346Fbe5d02c89FB4599F33BDCE987981D573740a
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000803e2b13a11c21ec0616cead4a3d2ebe1326f5b0
Arg [1] : 000000000000000000000000d4af09f41c674141e9f8c1ce2883f08ecafd6649
Arg [2] : 000000000000000000000000346fbe5d02c89fb4599f33bdce987981d573740a
Swarm Source
bzzr://2d6c873b7b3337a5d038ea363fc051b5760cbd1050a2f84ec851f65aba9668f8
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.