More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,492 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 6458611 | 2251 days ago | IN | 0.20043625 ETH | 0.00014732 | ||||
__callback | 6005735 | 2327 days ago | IN | 0 ETH | 0.00173161 | ||||
__callback | 5977023 | 2332 days ago | IN | 0 ETH | 0.00066015 | ||||
Set Game Paused | 5975970 | 2332 days ago | IN | 0 ETH | 0.00011097 | ||||
__callback | 5973944 | 2332 days ago | IN | 0 ETH | 0.00239553 | ||||
Play | 5973691 | 2332 days ago | IN | 0.06087 ETH | 0.00191459 | ||||
__callback | 5973651 | 2332 days ago | IN | 0 ETH | 0.00231599 | ||||
Play | 5973634 | 2332 days ago | IN | 0.048456 ETH | 0.00164146 | ||||
Play | 5953943 | 2336 days ago | IN | 0.03 ETH | 0.00218498 | ||||
Play | 5948889 | 2337 days ago | IN | 0.023 ETH | 0.00034225 | ||||
Play | 5948877 | 2337 days ago | IN | 0.023 ETH | 0.00026327 | ||||
__callback | 5948586 | 2337 days ago | IN | 0 ETH | 0.00066213 | ||||
Refund | 5948072 | 2337 days ago | IN | 0 ETH | 0.00046201 | ||||
Play | 5945285 | 2337 days ago | IN | 0.048816 ETH | 0.00300435 | ||||
__callback | 5945275 | 2337 days ago | IN | 0 ETH | 0.00217375 | ||||
Play | 5945264 | 2337 days ago | IN | 0.048792 ETH | 0.00303166 | ||||
__callback | 5944365 | 2337 days ago | IN | 0 ETH | 0.00219382 | ||||
Play | 5944333 | 2337 days ago | IN | 0.050725 ETH | 0.00300435 | ||||
__callback | 5944322 | 2337 days ago | IN | 0 ETH | 0.00221954 | ||||
Play | 5944316 | 2337 days ago | IN | 0.052442 ETH | 0.00273123 | ||||
Refund | 5939397 | 2338 days ago | IN | 0 ETH | 0.00060061 | ||||
__callback | 5937240 | 2339 days ago | IN | 0 ETH | 0.00066277 | ||||
__callback | 5936278 | 2339 days ago | IN | 0 ETH | 0.00066277 | ||||
__callback | 5935726 | 2339 days ago | IN | 0 ETH | 0.0025502 | ||||
Play | 5935576 | 2339 days ago | IN | 0.052494 ETH | 0.0024581 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
6093994 | 2312 days ago | 0.00139326 ETH | ||||
6005735 | 2327 days ago | 0.0297 ETH | ||||
5973944 | 2332 days ago | 0.0602613 ETH | ||||
5973691 | 2332 days ago | 0.00279438 ETH | ||||
5973691 | 2332 days ago | 0.00279438 ETH | ||||
5973651 | 2332 days ago | 0.04797144 ETH | ||||
5973634 | 2332 days ago | 0.00259818 ETH | ||||
5973634 | 2332 days ago | 0.00259818 ETH | ||||
5953943 | 2336 days ago | 0.00214038 ETH | ||||
5953943 | 2336 days ago | 0.00214038 ETH | ||||
5953504 | 2336 days ago | 0.16726612 ETH | ||||
5948072 | 2337 days ago | 0.048816 ETH | ||||
5945285 | 2337 days ago | 0.00261815 ETH | ||||
5945285 | 2337 days ago | 0.00261815 ETH | ||||
5945275 | 2337 days ago | 0.04830408 ETH | ||||
5945264 | 2337 days ago | 0.00261815 ETH | ||||
5945264 | 2337 days ago | 0.00261815 ETH | ||||
5944365 | 2337 days ago | 0.05021775 ETH | ||||
5944333 | 2337 days ago | 0.00265085 ETH | ||||
5944333 | 2337 days ago | 0.00265085 ETH | ||||
5944322 | 2337 days ago | 0.05191758 ETH | ||||
5944316 | 2337 days ago | 0.00268355 ETH | ||||
5944316 | 2337 days ago | 0.00268355 ETH | ||||
5939397 | 2338 days ago | 0.052494 ETH | ||||
5935576 | 2339 days ago | 0.00268355 ETH |
Loading...
Loading
Contract Name:
EOSBetSlots
Compiler Version
v0.4.21+commit.dfe3193c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2018-04-10 */ pragma solidity ^0.4.21; contract OraclizeI { address public cbAddress; function query(uint _timestamp, string _datasource, string _arg) external payable returns (bytes32 _id); function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit) external payable returns (bytes32 _id); function query2(uint _timestamp, string _datasource, string _arg1, string _arg2) public payable returns (bytes32 _id); function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit) external payable returns (bytes32 _id); function queryN(uint _timestamp, string _datasource, bytes _argN) public payable returns (bytes32 _id); function queryN_withGasLimit(uint _timestamp, string _datasource, bytes _argN, uint _gaslimit) external payable returns (bytes32 _id); function getPrice(string _datasource) public returns (uint _dsprice); function getPrice(string _datasource, uint gaslimit) public returns (uint _dsprice); function setProofType(byte _proofType) external; function setCustomGasPrice(uint _gasPrice) external; function randomDS_getSessionPubKeyHash() external constant returns(bytes32); } contract OraclizeAddrResolverI { function getAddress() public returns (address _addr); } contract usingOraclize { uint constant day = 60*60*24; uint constant week = 60*60*24*7; uint constant month = 60*60*24*30; byte constant proofType_NONE = 0x00; byte constant proofType_TLSNotary = 0x10; byte constant proofType_Android = 0x20; byte constant proofType_Ledger = 0x30; byte constant proofType_Native = 0xF0; byte constant proofStorage_IPFS = 0x01; uint8 constant networkID_auto = 0; uint8 constant networkID_mainnet = 1; uint8 constant networkID_testnet = 2; uint8 constant networkID_morden = 2; uint8 constant networkID_consensys = 161; OraclizeAddrResolverI OAR; OraclizeI oraclize; modifier oraclizeAPI { if((address(OAR)==0)||(getCodeSize(address(OAR))==0)) oraclize_setNetwork(networkID_auto); if(address(oraclize) != OAR.getAddress()) oraclize = OraclizeI(OAR.getAddress()); _; } modifier coupon(string code){ oraclize = OraclizeI(OAR.getAddress()); _; } function oraclize_setNetwork(uint8 networkID) internal returns(bool){ return oraclize_setNetwork(); networkID; // silence the warning and remain backwards compatible } function oraclize_setNetwork() internal returns(bool){ if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed); oraclize_setNetworkName("eth_mainnet"); return true; } if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){ //ropsten testnet OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1); oraclize_setNetworkName("eth_ropsten3"); return true; } if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){ //kovan testnet OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e); oraclize_setNetworkName("eth_kovan"); return true; } if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48)>0){ //rinkeby testnet OAR = OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48); oraclize_setNetworkName("eth_rinkeby"); return true; } if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475)>0){ //ethereum-bridge OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475); return true; } if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF)>0){ //ether.camp ide OAR = OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF); return true; } if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA)>0){ //browser-solidity OAR = OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA); return true; } return false; } function __callback(bytes32 myid, string result) public { __callback(myid, result, new bytes(0)); } function __callback(bytes32 myid, string result, bytes proof) public { return; myid; result; proof; // Silence compiler warnings } function oraclize_getPrice(string datasource) oraclizeAPI internal returns (uint){ return oraclize.getPrice(datasource); } function oraclize_getPrice(string datasource, uint gaslimit) oraclizeAPI internal returns (uint){ return oraclize.getPrice(datasource, gaslimit); } function oraclize_query(string datasource, string arg) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price return oraclize.query.value(price)(0, datasource, arg); } function oraclize_query(uint timestamp, string datasource, string arg) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price return oraclize.query.value(price)(timestamp, datasource, arg); } function oraclize_query(uint timestamp, string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price return oraclize.query_withGasLimit.value(price)(timestamp, datasource, arg, gaslimit); } function oraclize_query(string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price return oraclize.query_withGasLimit.value(price)(0, datasource, arg, gaslimit); } function oraclize_query(string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price return oraclize.query2.value(price)(0, datasource, arg1, arg2); } function oraclize_query(uint timestamp, string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price return oraclize.query2.value(price)(timestamp, datasource, arg1, arg2); } function oraclize_query(uint timestamp, string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price return oraclize.query2_withGasLimit.value(price)(timestamp, datasource, arg1, arg2, gaslimit); } function oraclize_query(string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price return oraclize.query2_withGasLimit.value(price)(0, datasource, arg1, arg2, gaslimit); } function oraclize_query(string datasource, string[] argN) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price bytes memory args = stra2cbor(argN); return oraclize.queryN.value(price)(0, datasource, args); } function oraclize_query(uint timestamp, string datasource, string[] argN) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price bytes memory args = stra2cbor(argN); return oraclize.queryN.value(price)(timestamp, datasource, args); } function oraclize_query(uint timestamp, string datasource, string[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price bytes memory args = stra2cbor(argN); return oraclize.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit); } function oraclize_query(string datasource, string[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price bytes memory args = stra2cbor(argN); return oraclize.queryN_withGasLimit.value(price)(0, datasource, args, gaslimit); } function oraclize_query(string datasource, string[1] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](1); dynargs[0] = args[0]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[1] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](1); dynargs[0] = args[0]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](1); dynargs[0] = args[0]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](1); dynargs[0] = args[0]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[2] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[2] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[3] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[3] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[4] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[4] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[5] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[5] args) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, string[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, string[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { string[] memory dynargs = new string[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[] argN) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price bytes memory args = ba2cbor(argN); return oraclize.queryN.value(price)(0, datasource, args); } function oraclize_query(uint timestamp, string datasource, bytes[] argN) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource); if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price bytes memory args = ba2cbor(argN); return oraclize.queryN.value(price)(timestamp, datasource, args); } function oraclize_query(uint timestamp, string datasource, bytes[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price bytes memory args = ba2cbor(argN); return oraclize.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit); } function oraclize_query(string datasource, bytes[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){ uint price = oraclize.getPrice(datasource, gaslimit); if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price bytes memory args = ba2cbor(argN); return oraclize.queryN_withGasLimit.value(price)(0, datasource, args, gaslimit); } function oraclize_query(string datasource, bytes[1] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](1); dynargs[0] = args[0]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[1] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](1); dynargs[0] = args[0]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](1); dynargs[0] = args[0]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](1); dynargs[0] = args[0]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[2] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[2] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](2); dynargs[0] = args[0]; dynargs[1] = args[1]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[3] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[3] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](3); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[4] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[4] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](4); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[5] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[5] args) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(timestamp, datasource, dynargs); } function oraclize_query(uint timestamp, string datasource, bytes[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(timestamp, datasource, dynargs, gaslimit); } function oraclize_query(string datasource, bytes[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) { bytes[] memory dynargs = new bytes[](5); dynargs[0] = args[0]; dynargs[1] = args[1]; dynargs[2] = args[2]; dynargs[3] = args[3]; dynargs[4] = args[4]; return oraclize_query(datasource, dynargs, gaslimit); } function oraclize_cbAddress() oraclizeAPI internal returns (address){ return oraclize.cbAddress(); } function oraclize_setProof(byte proofP) oraclizeAPI internal { return oraclize.setProofType(proofP); } function oraclize_setCustomGasPrice(uint gasPrice) oraclizeAPI internal { return oraclize.setCustomGasPrice(gasPrice); } function oraclize_randomDS_getSessionPubKeyHash() oraclizeAPI internal returns (bytes32){ return oraclize.randomDS_getSessionPubKeyHash(); } function getCodeSize(address _addr) constant internal returns(uint _size) { assembly { _size := extcodesize(_addr) } } function parseAddr(string _a) internal pure returns (address){ bytes memory tmp = bytes(_a); uint160 iaddr = 0; uint160 b1; uint160 b2; for (uint i=2; i<2+2*20; i+=2){ iaddr *= 256; b1 = uint160(tmp[i]); b2 = uint160(tmp[i+1]); if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87; else if ((b1 >= 65)&&(b1 <= 70)) b1 -= 55; else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48; if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87; else if ((b2 >= 65)&&(b2 <= 70)) b2 -= 55; else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48; iaddr += (b1*16+b2); } return address(iaddr); } function strCompare(string _a, string _b) internal pure returns (int) { bytes memory a = bytes(_a); bytes memory b = bytes(_b); uint minLength = a.length; if (b.length < minLength) minLength = b.length; for (uint i = 0; i < minLength; i ++) if (a[i] < b[i]) return -1; else if (a[i] > b[i]) return 1; if (a.length < b.length) return -1; else if (a.length > b.length) return 1; else return 0; } function indexOf(string _haystack, string _needle) internal pure returns (int) { bytes memory h = bytes(_haystack); bytes memory n = bytes(_needle); if(h.length < 1 || n.length < 1 || (n.length > h.length)) return -1; else if(h.length > (2**128 -1)) return -1; else { uint subindex = 0; for (uint i = 0; i < h.length; i ++) { if (h[i] == n[0]) { subindex = 1; while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex]) { subindex++; } if(subindex == n.length) return int(i); } } return -1; } } function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory _bc = bytes(_c); bytes memory _bd = bytes(_d); bytes memory _be = bytes(_e); string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); bytes memory babcde = bytes(abcde); uint k = 0; for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; for (i = 0; i < _be.length; i++) babcde[k++] = _be[i]; return string(babcde); } function strConcat(string _a, string _b, string _c, string _d) internal pure returns (string) { return strConcat(_a, _b, _c, _d, ""); } function strConcat(string _a, string _b, string _c) internal pure returns (string) { return strConcat(_a, _b, _c, "", ""); } function strConcat(string _a, string _b) internal pure returns (string) { return strConcat(_a, _b, "", "", ""); } // parseInt function parseInt(string _a) internal pure returns (uint) { return parseInt(_a, 0); } // parseInt(parseFloat*10^_b) function parseInt(string _a, uint _b) internal pure returns (uint) { bytes memory bresult = bytes(_a); uint mint = 0; bool decimals = false; for (uint i=0; i<bresult.length; i++){ if ((bresult[i] >= 48)&&(bresult[i] <= 57)){ if (decimals){ if (_b == 0) break; else _b--; } mint *= 10; mint += uint(bresult[i]) - 48; } else if (bresult[i] == 46) decimals = true; } if (_b > 0) mint *= 10**_b; return mint; } function uint2str(uint i) internal pure returns (string){ if (i == 0) return "0"; uint j = i; uint len; while (j != 0){ len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (i != 0){ bstr[k--] = byte(48 + i % 10); i /= 10; } return string(bstr); } function stra2cbor(string[] arr) internal pure returns (bytes) { uint arrlen = arr.length; // get correct cbor output length uint outputlen = 0; bytes[] memory elemArray = new bytes[](arrlen); for (uint i = 0; i < arrlen; i++) { elemArray[i] = (bytes(arr[i])); outputlen += elemArray[i].length + (elemArray[i].length - 1)/23 + 3; //+3 accounts for paired identifier types } uint ctr = 0; uint cborlen = arrlen + 0x80; outputlen += byte(cborlen).length; bytes memory res = new bytes(outputlen); while (byte(cborlen).length > ctr) { res[ctr] = byte(cborlen)[ctr]; ctr++; } for (i = 0; i < arrlen; i++) { res[ctr] = 0x5F; ctr++; for (uint x = 0; x < elemArray[i].length; x++) { // if there's a bug with larger strings, this may be the culprit if (x % 23 == 0) { uint elemcborlen = elemArray[i].length - x >= 24 ? 23 : elemArray[i].length - x; elemcborlen += 0x40; uint lctr = ctr; while (byte(elemcborlen).length > ctr - lctr) { res[ctr] = byte(elemcborlen)[ctr - lctr]; ctr++; } } res[ctr] = elemArray[i][x]; ctr++; } res[ctr] = 0xFF; ctr++; } return res; } function ba2cbor(bytes[] arr) internal pure returns (bytes) { uint arrlen = arr.length; // get correct cbor output length uint outputlen = 0; bytes[] memory elemArray = new bytes[](arrlen); for (uint i = 0; i < arrlen; i++) { elemArray[i] = (bytes(arr[i])); outputlen += elemArray[i].length + (elemArray[i].length - 1)/23 + 3; //+3 accounts for paired identifier types } uint ctr = 0; uint cborlen = arrlen + 0x80; outputlen += byte(cborlen).length; bytes memory res = new bytes(outputlen); while (byte(cborlen).length > ctr) { res[ctr] = byte(cborlen)[ctr]; ctr++; } for (i = 0; i < arrlen; i++) { res[ctr] = 0x5F; ctr++; for (uint x = 0; x < elemArray[i].length; x++) { // if there's a bug with larger strings, this may be the culprit if (x % 23 == 0) { uint elemcborlen = elemArray[i].length - x >= 24 ? 23 : elemArray[i].length - x; elemcborlen += 0x40; uint lctr = ctr; while (byte(elemcborlen).length > ctr - lctr) { res[ctr] = byte(elemcborlen)[ctr - lctr]; ctr++; } } res[ctr] = elemArray[i][x]; ctr++; } res[ctr] = 0xFF; ctr++; } return res; } string oraclize_network_name; function oraclize_setNetworkName(string _network_name) internal { oraclize_network_name = _network_name; } function oraclize_getNetworkName() internal view returns (string) { return oraclize_network_name; } function oraclize_newRandomDSQuery(uint _delay, uint _nbytes, uint _customGasLimit) internal returns (bytes32){ require((_nbytes > 0) && (_nbytes <= 32)); // Convert from seconds to ledger timer ticks _delay *= 10; bytes memory nbytes = new bytes(1); nbytes[0] = byte(_nbytes); bytes memory unonce = new bytes(32); bytes memory sessionKeyHash = new bytes(32); bytes32 sessionKeyHash_bytes32 = oraclize_randomDS_getSessionPubKeyHash(); assembly { mstore(unonce, 0x20) mstore(add(unonce, 0x20), xor(blockhash(sub(number, 1)), xor(coinbase, timestamp))) mstore(sessionKeyHash, 0x20) mstore(add(sessionKeyHash, 0x20), sessionKeyHash_bytes32) } bytes memory delay = new bytes(32); assembly { mstore(add(delay, 0x20), _delay) } bytes memory delay_bytes8 = new bytes(8); copyBytes(delay, 24, 8, delay_bytes8, 0); bytes[4] memory args = [unonce, nbytes, sessionKeyHash, delay]; bytes32 queryId = oraclize_query("random", args, _customGasLimit); bytes memory delay_bytes8_left = new bytes(8); assembly { let x := mload(add(delay_bytes8, 0x20)) mstore8(add(delay_bytes8_left, 0x27), div(x, 0x100000000000000000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x26), div(x, 0x1000000000000000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x25), div(x, 0x10000000000000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x24), div(x, 0x100000000000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x23), div(x, 0x1000000000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x22), div(x, 0x10000000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x21), div(x, 0x100000000000000000000000000000000000000000000000000)) mstore8(add(delay_bytes8_left, 0x20), div(x, 0x1000000000000000000000000000000000000000000000000)) } oraclize_randomDS_setCommitment(queryId, keccak256(delay_bytes8_left, args[1], sha256(args[0]), args[2])); return queryId; } function oraclize_randomDS_setCommitment(bytes32 queryId, bytes32 commitment) internal { oraclize_randomDS_args[queryId] = commitment; } mapping(bytes32=>bytes32) oraclize_randomDS_args; mapping(bytes32=>bool) oraclize_randomDS_sessionKeysHashVerified; function verifySig(bytes32 tosignh, bytes dersig, bytes pubkey) internal returns (bool){ bool sigok; address signer; bytes32 sigr; bytes32 sigs; bytes memory sigr_ = new bytes(32); uint offset = 4+(uint(dersig[3]) - 0x20); sigr_ = copyBytes(dersig, offset, 32, sigr_, 0); bytes memory sigs_ = new bytes(32); offset += 32 + 2; sigs_ = copyBytes(dersig, offset+(uint(dersig[offset-1]) - 0x20), 32, sigs_, 0); assembly { sigr := mload(add(sigr_, 32)) sigs := mload(add(sigs_, 32)) } (sigok, signer) = safer_ecrecover(tosignh, 27, sigr, sigs); if (address(keccak256(pubkey)) == signer) return true; else { (sigok, signer) = safer_ecrecover(tosignh, 28, sigr, sigs); return (address(keccak256(pubkey)) == signer); } } function oraclize_randomDS_proofVerify__sessionKeyValidity(bytes proof, uint sig2offset) internal returns (bool) { bool sigok; // Step 6: verify the attestation signature, APPKEY1 must sign the sessionKey from the correct ledger app (CODEHASH) bytes memory sig2 = new bytes(uint(proof[sig2offset+1])+2); copyBytes(proof, sig2offset, sig2.length, sig2, 0); bytes memory appkey1_pubkey = new bytes(64); copyBytes(proof, 3+1, 64, appkey1_pubkey, 0); bytes memory tosign2 = new bytes(1+65+32); tosign2[0] = byte(1); //role copyBytes(proof, sig2offset-65, 65, tosign2, 1); bytes memory CODEHASH = hex"fd94fa71bc0ba10d39d464d0d8f465efeef0a2764e3887fcc9df41ded20f505c"; copyBytes(CODEHASH, 0, 32, tosign2, 1+65); sigok = verifySig(sha256(tosign2), sig2, appkey1_pubkey); if (sigok == false) return false; // Step 7: verify the APPKEY1 provenance (must be signed by Ledger) bytes memory LEDGERKEY = hex"7fb956469c5c9b89840d55b43537e66a98dd4811ea0a27224272c2e5622911e8537a2f8e86a46baec82864e98dd01e9ccc2f8bc5dfc9cbe5a91a290498dd96e4"; bytes memory tosign3 = new bytes(1+65); tosign3[0] = 0xFE; copyBytes(proof, 3, 65, tosign3, 1); bytes memory sig3 = new bytes(uint(proof[3+65+1])+2); copyBytes(proof, 3+65, sig3.length, sig3, 0); sigok = verifySig(sha256(tosign3), sig3, LEDGERKEY); return sigok; } modifier oraclize_randomDS_proofVerify(bytes32 _queryId, string _result, bytes _proof) { // Step 1: the prefix has to match 'LP\x01' (Ledger Proof version 1) require((_proof[0] == "L") && (_proof[1] == "P") && (_proof[2] == 1)); bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName()); require(proofVerified); _; } function oraclize_randomDS_proofVerify__returnCode(bytes32 _queryId, string _result, bytes _proof) internal returns (uint8){ // Step 1: the prefix has to match 'LP\x01' (Ledger Proof version 1) if ((_proof[0] != "L")||(_proof[1] != "P")||(_proof[2] != 1)) return 1; bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName()); if (proofVerified == false) return 2; return 0; } function matchBytes32Prefix(bytes32 content, bytes prefix, uint n_random_bytes) internal pure returns (bool){ bool match_ = true; require(prefix.length == n_random_bytes); for (uint256 i=0; i< n_random_bytes; i++) { if (content[i] != prefix[i]) match_ = false; } return match_; } function oraclize_randomDS_proofVerify__main(bytes proof, bytes32 queryId, bytes result, string context_name) internal returns (bool){ // Step 2: the unique keyhash has to match with the sha256 of (context name + queryId) uint ledgerProofLength = 3+65+(uint(proof[3+65+1])+2)+32; bytes memory keyhash = new bytes(32); copyBytes(proof, ledgerProofLength, 32, keyhash, 0); if (!(keccak256(keyhash) == keccak256(sha256(context_name, queryId)))) return false; bytes memory sig1 = new bytes(uint(proof[ledgerProofLength+(32+8+1+32)+1])+2); copyBytes(proof, ledgerProofLength+(32+8+1+32), sig1.length, sig1, 0); // Step 3: we assume sig1 is valid (it will be verified during step 5) and we verify if 'result' is the prefix of sha256(sig1) if (!matchBytes32Prefix(sha256(sig1), result, uint(proof[ledgerProofLength+32+8]))) return false; // Step 4: commitment match verification, keccak256(delay, nbytes, unonce, sessionKeyHash) == commitment in storage. // This is to verify that the computed args match with the ones specified in the query. bytes memory commitmentSlice1 = new bytes(8+1+32); copyBytes(proof, ledgerProofLength+32, 8+1+32, commitmentSlice1, 0); bytes memory sessionPubkey = new bytes(64); uint sig2offset = ledgerProofLength+32+(8+1+32)+sig1.length+65; copyBytes(proof, sig2offset-64, 64, sessionPubkey, 0); bytes32 sessionPubkeyHash = sha256(sessionPubkey); if (oraclize_randomDS_args[queryId] == keccak256(commitmentSlice1, sessionPubkeyHash)){ //unonce, nbytes and sessionKeyHash match delete oraclize_randomDS_args[queryId]; } else return false; // Step 5: validity verification for sig1 (keyhash and args signed with the sessionKey) bytes memory tosign1 = new bytes(32+8+1+32); copyBytes(proof, ledgerProofLength, 32+8+1+32, tosign1, 0); if (!verifySig(sha256(tosign1), sig1, sessionPubkey)) return false; // verify if sessionPubkeyHash was verified already, if not.. let's do it! if (oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] == false){ oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] = oraclize_randomDS_proofVerify__sessionKeyValidity(proof, sig2offset); } return oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash]; } // the following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license function copyBytes(bytes from, uint fromOffset, uint length, bytes to, uint toOffset) internal pure returns (bytes) { uint minLength = length + toOffset; // Buffer too small require(to.length >= minLength); // Should be a better way? // NOTE: the offset 32 is added to skip the `size` field of both bytes variables uint i = 32 + fromOffset; uint j = 32 + toOffset; while (i < (32 + fromOffset + length)) { assembly { let tmp := mload(add(from, i)) mstore(add(to, j), tmp) } i += 32; j += 32; } return to; } // the following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license // Duplicate Solidity's ecrecover, but catching the CALL return value function safer_ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal returns (bool, address) { // We do our own memory management here. Solidity uses memory offset // 0x40 to store the current end of memory. We write past it (as // writes are memory extensions), but don't update the offset so // Solidity will reuse it. The memory used here is only needed for // this context. // FIXME: inline assembly can't access return values bool ret; address addr; assembly { let size := mload(0x40) mstore(size, hash) mstore(add(size, 32), v) mstore(add(size, 64), r) mstore(add(size, 96), s) // NOTE: we can reuse the request memory because we deal with // the return code ret := call(3000, 1, 0, size, 128, size, 32) addr := mload(size) } return (ret, addr); } // the following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license function ecrecovery(bytes32 hash, bytes sig) internal returns (bool, address) { bytes32 r; bytes32 s; uint8 v; if (sig.length != 65) return (false, 0); // The signature format is a compact form of: // {bytes32 r}{bytes32 s}{uint8 v} // Compact means, uint8 is not padded to 32 bytes. assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) // Here we are loading the last 32 bytes. We exploit the fact that // 'mload' will pad with zeroes if we overread. // There is no 'mload8' to do this, but that would be nicer. v := byte(0, mload(add(sig, 96))) // Alternative solution: // 'byte' is not working due to the Solidity parser, so lets // use the second best option, 'and' // v := and(mload(add(sig, 65)), 255) } // albeit non-transactional signatures are not specified by the YP, one would expect it // to match the YP range of [27, 28] // // geth uses [0, 1] and some clients have followed. This might change, see: // https://github.com/ethereum/go-ethereum/issues/2053 if (v < 27) v += 27; if (v != 27 && v != 28) return (false, 0); return safer_ecrecover(hash, v, r, s); } } // </ORACLIZE_API> contract EOSBetGameInterface { uint256 public DEVELOPERSFUND; uint256 public LIABILITIES; function payDevelopersFund(address developer) public; function receivePaymentForOraclize() payable public; function getMaxWin() public view returns(uint256); } contract EOSBetBankrollInterface { function payEtherToWinner(uint256 amtEther, address winner) public; function receiveEtherFromGameAddress() payable public; function payOraclize(uint256 amountToPay) public; function getBankroll() public view returns(uint256); } contract ERC20 { function totalSupply() constant public returns (uint supply); function balanceOf(address _owner) constant public 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) constant public returns (uint remaining); event Transfer(address indexed _from, address indexed _to, uint _value); event Approval(address indexed _owner, address indexed _spender, uint _value); } contract EOSBetBankroll is ERC20, EOSBetBankrollInterface { using SafeMath for *; // constants for EOSBet Bankroll address public OWNER; uint256 public MAXIMUMINVESTMENTSALLOWED; uint256 public WAITTIMEUNTILWITHDRAWORTRANSFER; uint256 public DEVELOPERSFUND; // this will be initialized as the trusted game addresses which will forward their ether // to the bankroll contract, and when players win, they will request the bankroll contract // to send these players their winnings. // Feel free to audit these contracts on etherscan... mapping(address => bool) public TRUSTEDADDRESSES; address public DICE; address public SLOTS; // mapping to log the last time a user contributed to the bankroll mapping(address => uint256) contributionTime; // constants for ERC20 standard string public constant name = "EOSBet Stake Tokens"; string public constant symbol = "EOSBETST"; uint8 public constant decimals = 18; // variable total supply uint256 public totalSupply; // mapping to store tokens mapping(address => uint256) public balances; mapping(address => mapping(address => uint256)) public allowed; // events event FundBankroll(address contributor, uint256 etherContributed, uint256 tokensReceived); event CashOut(address contributor, uint256 etherWithdrawn, uint256 tokensCashedIn); event FailedSend(address sendTo, uint256 amt); // checks that an address is a "trusted address of a legitimate EOSBet game" modifier addressInTrustedAddresses(address thisAddress){ require(TRUSTEDADDRESSES[thisAddress]); _; } // initialization function function EOSBetBankroll(address dice, address slots) public payable { // function is payable, owner of contract MUST "seed" contract with some ether, // so that the ratios are correct when tokens are being minted require (msg.value > 0); OWNER = msg.sender; // 100 tokens/ether is the inital seed amount, so: uint256 initialTokens = msg.value * 100; balances[msg.sender] = initialTokens; totalSupply = initialTokens; // log a mint tokens event emit Transfer(0x0, msg.sender, initialTokens); // insert given game addresses into the TRUSTEDADDRESSES mapping, and save the addresses as global variables TRUSTEDADDRESSES[dice] = true; TRUSTEDADDRESSES[slots] = true; DICE = dice; SLOTS = slots; WAITTIMEUNTILWITHDRAWORTRANSFER = 6 hours; MAXIMUMINVESTMENTSALLOWED = 500 ether; } /////////////////////////////////////////////// // VIEW FUNCTIONS /////////////////////////////////////////////// function checkWhenContributorCanTransferOrWithdraw(address bankrollerAddress) view public returns(uint256){ return contributionTime[bankrollerAddress]; } function getBankroll() view public returns(uint256){ // returns the total balance minus the developers fund, as the amount of active bankroll return SafeMath.sub(address(this).balance, DEVELOPERSFUND); } /////////////////////////////////////////////// // BANKROLL CONTRACT <-> GAME CONTRACTS functions /////////////////////////////////////////////// function payEtherToWinner(uint256 amtEther, address winner) public addressInTrustedAddresses(msg.sender){ // this function will get called by a game contract when someone wins a game // try to send, if it fails, then send the amount to the owner // note, this will only happen if someone is calling the betting functions with // a contract. They are clearly up to no good, so they can contact us to retreive // their ether // if the ether cannot be sent to us, the OWNER, that means we are up to no good, // and the ether will just be given to the bankrollers as if the player/owner lost if (! winner.send(amtEther)){ emit FailedSend(winner, amtEther); if (! OWNER.send(amtEther)){ emit FailedSend(OWNER, amtEther); } } } function receiveEtherFromGameAddress() payable public addressInTrustedAddresses(msg.sender){ // this function will get called from the game contracts when someone starts a game. } function payOraclize(uint256 amountToPay) public addressInTrustedAddresses(msg.sender){ // this function will get called when a game contract must pay payOraclize EOSBetGameInterface(msg.sender).receivePaymentForOraclize.value(amountToPay)(); } /////////////////////////////////////////////// // BANKROLL CONTRACT MAIN FUNCTIONS /////////////////////////////////////////////// // this function ADDS to the bankroll of EOSBet, and credits the bankroller a proportional // amount of tokens so they may withdraw their tokens later // also if there is only a limited amount of space left in the bankroll, a user can just send as much // ether as they want, because they will be able to contribute up to the maximum, and then get refunded the rest. function () public payable { // save in memory for cheap access. // this represents the total bankroll balance before the function was called. uint256 currentTotalBankroll = SafeMath.sub(getBankroll(), msg.value); uint256 maxInvestmentsAllowed = MAXIMUMINVESTMENTSALLOWED; require(currentTotalBankroll < maxInvestmentsAllowed && msg.value != 0); uint256 currentSupplyOfTokens = totalSupply; uint256 contributedEther; bool contributionTakesBankrollOverLimit; uint256 ifContributionTakesBankrollOverLimit_Refund; uint256 creditedTokens; if (SafeMath.add(currentTotalBankroll, msg.value) > maxInvestmentsAllowed){ // allow the bankroller to contribute up to the allowed amount of ether, and refund the rest. contributionTakesBankrollOverLimit = true; // set contributed ether as (MAXIMUMINVESTMENTSALLOWED - BANKROLL) contributedEther = SafeMath.sub(maxInvestmentsAllowed, currentTotalBankroll); // refund the rest of the ether, which is (original amount sent - (maximum amount allowed - bankroll)) ifContributionTakesBankrollOverLimit_Refund = SafeMath.sub(msg.value, contributedEther); } else { contributedEther = msg.value; } if (currentSupplyOfTokens != 0){ // determine the ratio of contribution versus total BANKROLL. creditedTokens = SafeMath.mul(contributedEther, currentSupplyOfTokens) / currentTotalBankroll; } else { // edge case where ALL money was cashed out from bankroll // so currentSupplyOfTokens == 0 // currentTotalBankroll can == 0 or not, if someone mines/selfdestruct's to the contract // but either way, give all the bankroll to person who deposits ether creditedTokens = SafeMath.mul(contributedEther, 100); } // now update the total supply of tokens and bankroll amount totalSupply = SafeMath.add(currentSupplyOfTokens, creditedTokens); // now credit the user with his amount of contributed tokens balances[msg.sender] = SafeMath.add(balances[msg.sender], creditedTokens); // update his contribution time for stake time locking contributionTime[msg.sender] = block.timestamp; // now look if the attempted contribution would have taken the BANKROLL over the limit, // and if true, refund the excess ether. if (contributionTakesBankrollOverLimit){ msg.sender.transfer(ifContributionTakesBankrollOverLimit_Refund); } // log an event about funding bankroll emit FundBankroll(msg.sender, contributedEther, creditedTokens); // log a mint tokens event emit Transfer(0x0, msg.sender, creditedTokens); } function cashoutEOSBetStakeTokens(uint256 _amountTokens) public { // In effect, this function is the OPPOSITE of the un-named payable function above^^^ // this allows bankrollers to "cash out" at any time, and receive the ether that they contributed, PLUS // a proportion of any ether that was earned by the smart contact when their ether was "staking", However // this works in reverse as well. Any net losses of the smart contract will be absorbed by the player in like manner. // Of course, due to the constant house edge, a bankroller that leaves their ether in the contract long enough // is effectively guaranteed to withdraw more ether than they originally "staked" // save in memory for cheap access. uint256 tokenBalance = balances[msg.sender]; // verify that the contributor has enough tokens to cash out this many, and has waited the required time. require(_amountTokens <= tokenBalance && contributionTime[msg.sender] + WAITTIMEUNTILWITHDRAWORTRANSFER <= block.timestamp && _amountTokens > 0); // save in memory for cheap access. // again, represents the total balance of the contract before the function was called. uint256 currentTotalBankroll = getBankroll(); uint256 currentSupplyOfTokens = totalSupply; // calculate the token withdraw ratio based on current supply uint256 withdrawEther = SafeMath.mul(_amountTokens, currentTotalBankroll) / currentSupplyOfTokens; // developers take 1% of withdrawls uint256 developersCut = withdrawEther / 100; uint256 contributorAmount = SafeMath.sub(withdrawEther, developersCut); // now update the total supply of tokens by subtracting the tokens that are being "cashed in" totalSupply = SafeMath.sub(currentSupplyOfTokens, _amountTokens); // and update the users supply of tokens balances[msg.sender] = SafeMath.sub(tokenBalance, _amountTokens); // update the developers fund based on this calculated amount DEVELOPERSFUND = SafeMath.add(DEVELOPERSFUND, developersCut); // lastly, transfer the ether back to the bankroller. Thanks for your contribution! msg.sender.transfer(contributorAmount); // log an event about cashout emit CashOut(msg.sender, contributorAmount, _amountTokens); // log a destroy tokens event emit Transfer(msg.sender, 0x0, _amountTokens); } // TO CALL THIS FUNCTION EASILY, SEND A 0 ETHER TRANSACTION TO THIS CONTRACT WITH EXTRA DATA: 0x7a09588b function cashoutEOSBetStakeTokens_ALL() public { // just forward to cashoutEOSBetStakeTokens with input as the senders entire balance cashoutEOSBetStakeTokens(balances[msg.sender]); } //////////////////// // OWNER FUNCTIONS: //////////////////// // Please, be aware that the owner ONLY can change: // 1. The owner can increase or decrease the target amount for a game. They can then call the updater function to give/receive the ether from the game. // 1. The wait time until a user can withdraw or transfer their tokens after purchase through the default function above ^^^ // 2. The owner can change the maximum amount of investments allowed. This allows for early contributors to guarantee // a certain percentage of the bankroll so that their stake cannot be diluted immediately. However, be aware that the // maximum amount of investments allowed will be raised over time. This will allow for higher bets by gamblers, resulting // in higher dividends for the bankrollers // 3. The owner can freeze payouts to bettors. This will be used in case of an emergency, and the contract will reject all // new bets as well. This does not mean that bettors will lose their money without recompense. They will be allowed to call the // "refund" function in the respective game smart contract once payouts are un-frozen. // 4. Finally, the owner can modify and withdraw the developers reward, which will fund future development, including new games, a sexier frontend, // and TRUE DAO governance so that onlyOwner functions don't have to exist anymore ;) and in order to effectively react to changes // in the market (lower the percentage because of increased competition in the blockchain casino space, etc.) function transferOwnership(address newOwner) public { require(msg.sender == OWNER); OWNER = newOwner; } function changeWaitTimeUntilWithdrawOrTransfer(uint256 waitTime) public { // waitTime MUST be less than or equal to 10 weeks require (msg.sender == OWNER && waitTime <= 6048000); WAITTIMEUNTILWITHDRAWORTRANSFER = waitTime; } function changeMaximumInvestmentsAllowed(uint256 maxAmount) public { require(msg.sender == OWNER); MAXIMUMINVESTMENTSALLOWED = maxAmount; } function withdrawDevelopersFund(address receiver) public { require(msg.sender == OWNER); // first get developers fund from each game EOSBetGameInterface(DICE).payDevelopersFund(receiver); EOSBetGameInterface(SLOTS).payDevelopersFund(receiver); // now send the developers fund from the main contract. uint256 developersFund = DEVELOPERSFUND; // set developers fund to zero DEVELOPERSFUND = 0; // transfer this amount to the owner! receiver.transfer(developersFund); } // rescue tokens inadvertently sent to the contract address function ERC20Rescue(address tokenAddress, uint256 amtTokens) public { require (msg.sender == OWNER); ERC20(tokenAddress).transfer(msg.sender, amtTokens); } /////////////////////////////// // BASIC ERC20 TOKEN OPERATIONS /////////////////////////////// function totalSupply() constant public returns(uint){ return totalSupply; } function balanceOf(address _owner) constant public returns(uint){ return balances[_owner]; } // don't allow transfers before the required wait-time // and don't allow transfers to this contract addr, it'll just kill tokens function transfer(address _to, uint256 _value) public returns (bool success){ require(balances[msg.sender] >= _value && contributionTime[msg.sender] + WAITTIMEUNTILWITHDRAWORTRANSFER <= block.timestamp && _to != address(this) && _to != address(0)); // safely subtract balances[msg.sender] = SafeMath.sub(balances[msg.sender], _value); balances[_to] = SafeMath.add(balances[_to], _value); // log event emit Transfer(msg.sender, _to, _value); return true; } // don't allow transfers before the required wait-time // and don't allow transfers to the contract addr, it'll just kill tokens function transferFrom(address _from, address _to, uint _value) public returns(bool){ require(allowed[_from][msg.sender] >= _value && balances[_from] >= _value && contributionTime[_from] + WAITTIMEUNTILWITHDRAWORTRANSFER <= block.timestamp && _to != address(this) && _to != address(0)); // safely add to _to and subtract from _from, and subtract from allowed balances. balances[_to] = SafeMath.add(balances[_to], _value); balances[_from] = SafeMath.sub(balances[_from], _value); allowed[_from][msg.sender] = SafeMath.sub(allowed[_from][msg.sender], _value); // log event emit Transfer(_from, _to, _value); return true; } function approve(address _spender, uint _value) public returns(bool){ allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); // log event return true; } function allowance(address _owner, address _spender) constant public returns(uint){ return allowed[_owner][_spender]; } } pragma solidity ^0.4.18; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } } contract EOSBetSlots is usingOraclize, EOSBetGameInterface { using SafeMath for *; // events event BuyCredits(bytes32 indexed oraclizeQueryId); event LedgerProofFailed(bytes32 indexed oraclizeQueryId); event Refund(bytes32 indexed oraclizeQueryId, uint256 amount); event SlotsLargeBet(bytes32 indexed oraclizeQueryId, uint256 data1, uint256 data2, uint256 data3, uint256 data4, uint256 data5, uint256 data6, uint256 data7, uint256 data8); event SlotsSmallBet(uint256 data1, uint256 data2, uint256 data3, uint256 data4, uint256 data5, uint256 data6, uint256 data7, uint256 data8); // slots game structure struct SlotsGameData { address player; bool paidOut; uint256 start; uint256 etherReceived; uint8 credits; } mapping (bytes32 => SlotsGameData) public slotsData; // ether in this contract can be in one of two locations: uint256 public LIABILITIES; uint256 public DEVELOPERSFUND; // counters for frontend statistics uint256 public AMOUNTWAGERED; uint256 public DIALSSPUN; // togglable values uint256 public ORACLIZEQUERYMAXTIME; uint256 public MINBET_perSPIN; uint256 public MINBET_perTX; uint256 public ORACLIZEGASPRICE; uint256 public INITIALGASFORORACLIZE; uint16 public MAXWIN_inTHOUSANDTHPERCENTS; // togglable functionality of contract bool public GAMEPAUSED; bool public REFUNDSACTIVE; // owner of contract address public OWNER; // bankroller address address public BANKROLLER; // constructor function EOSBetSlots() public { // ledger proof is ALWAYS verified on-chain oraclize_setProof(proofType_Ledger); // gas prices for oraclize call back, can be changed oraclize_setCustomGasPrice(8000000000); ORACLIZEGASPRICE = 8000000000; INITIALGASFORORACLIZE = 225000; AMOUNTWAGERED = 0; DIALSSPUN = 0; GAMEPAUSED = false; REFUNDSACTIVE = true; ORACLIZEQUERYMAXTIME = 6 hours; MINBET_perSPIN = 2 finney; // currently, this is ~40-50c a spin, which is pretty average slots. This is changeable by OWNER MINBET_perTX = 10 finney; MAXWIN_inTHOUSANDTHPERCENTS = 333; // 333/1000 so a jackpot can take 33% of bankroll (extremely rare) OWNER = msg.sender; } //////////////////////////////////// // INTERFACE CONTACT FUNCTIONS //////////////////////////////////// function payDevelopersFund(address developer) public { require(msg.sender == BANKROLLER); uint256 devFund = DEVELOPERSFUND; DEVELOPERSFUND = 0; developer.transfer(devFund); } // just a function to receive eth, only allow the bankroll to use this function receivePaymentForOraclize() payable public { require(msg.sender == BANKROLLER); } //////////////////////////////////// // VIEW FUNCTIONS //////////////////////////////////// function getMaxWin() public view returns(uint256){ return (SafeMath.mul(EOSBetBankrollInterface(BANKROLLER).getBankroll(), MAXWIN_inTHOUSANDTHPERCENTS) / 1000); } //////////////////////////////////// // OWNER ONLY FUNCTIONS //////////////////////////////////// // WARNING!!!!! Can only set this function once! function setBankrollerContractOnce(address bankrollAddress) public { // require that BANKROLLER address == 0x0 (address not set yet), and coming from owner. require(msg.sender == OWNER && BANKROLLER == address(0)); // check here to make sure that the bankroll contract is legitimate // just make sure that calling the bankroll contract getBankroll() returns non-zero require(EOSBetBankrollInterface(bankrollAddress).getBankroll() != 0); BANKROLLER = bankrollAddress; } function transferOwnership(address newOwner) public { require(msg.sender == OWNER); OWNER = newOwner; } function setOraclizeQueryMaxTime(uint256 newTime) public { require(msg.sender == OWNER); ORACLIZEQUERYMAXTIME = newTime; } // store the gas price as a storage variable for easy reference, // and thne change the gas price using the proper oraclize function function setOraclizeQueryGasPrice(uint256 gasPrice) public { require(msg.sender == OWNER); ORACLIZEGASPRICE = gasPrice; oraclize_setCustomGasPrice(gasPrice); } // should be ~160,000 to save eth function setInitialGasForOraclize(uint256 gasAmt) public { require(msg.sender == OWNER); INITIALGASFORORACLIZE = gasAmt; } function setGamePaused(bool paused) public { require(msg.sender == OWNER); GAMEPAUSED = paused; } function setRefundsActive(bool active) public { require(msg.sender == OWNER); REFUNDSACTIVE = active; } function setMinBetPerSpin(uint256 minBet) public { require(msg.sender == OWNER && minBet > 1000); MINBET_perSPIN = minBet; } function setMinBetPerTx(uint256 minBet) public { require(msg.sender == OWNER && minBet > 1000); MINBET_perTX = minBet; } function setMaxwin(uint16 newMaxWinInThousandthPercents) public { require(msg.sender == OWNER && newMaxWinInThousandthPercents <= 333); // cannot set max win greater than 1/3 of the bankroll (a jackpot is very rare) MAXWIN_inTHOUSANDTHPERCENTS = newMaxWinInThousandthPercents; } // rescue tokens inadvertently sent to the contract address function ERC20Rescue(address tokenAddress, uint256 amtTokens) public { require (msg.sender == OWNER); ERC20(tokenAddress).transfer(msg.sender, amtTokens); } function refund(bytes32 oraclizeQueryId) public { // save into memory for cheap access SlotsGameData memory data = slotsData[oraclizeQueryId]; //require that the query time is too slow, bet has not been paid out, and either contract owner or player is calling this function. require(SafeMath.sub(block.timestamp, data.start) >= ORACLIZEQUERYMAXTIME && (msg.sender == OWNER || msg.sender == data.player) && (!data.paidOut) && data.etherReceived <= LIABILITIES && data.etherReceived > 0 && REFUNDSACTIVE); // set contract data slotsData[oraclizeQueryId].paidOut = true; // subtract etherReceived from these two values because the bet is being refunded LIABILITIES = SafeMath.sub(LIABILITIES, data.etherReceived); // then transfer the original bet to the player. data.player.transfer(data.etherReceived); // finally, log an event saying that the refund has processed. emit Refund(oraclizeQueryId, data.etherReceived); } function play(uint8 credits) public payable { // save for future use / gas efficiency uint256 betPerCredit = msg.value / credits; // require that the game is unpaused, and that the credits being purchased are greater than 0 and less than the allowed amount, default: 100 spins // verify that the bet is less than or equal to the bet limit, so we don't go bankrupt, and that the etherreceived is greater than the minbet. require(!GAMEPAUSED && msg.value >= MINBET_perTX && betPerCredit >= MINBET_perSPIN && credits > 0 && credits <= 224 && SafeMath.mul(betPerCredit, 5000) <= getMaxWin()); // 5000 is the jackpot payout (max win on a roll) // equation for gas to oraclize is: // gas = (some fixed gas amt) + 3270 * credits uint256 gasToSend = INITIALGASFORORACLIZE + (uint256(3270) * credits); EOSBetBankrollInterface(BANKROLLER).payOraclize(oraclize_getPrice('random', gasToSend)); // oraclize_newRandomDSQuery(delay in seconds, bytes of random data, gas for callback function) bytes32 oraclizeQueryId = oraclize_newRandomDSQuery(0, 30, gasToSend); // add the new slots data to a mapping so that the oraclize __callback can use it later slotsData[oraclizeQueryId] = SlotsGameData({ player : msg.sender, paidOut : false, start : block.timestamp, etherReceived : msg.value, credits : credits }); // add the sent value into liabilities. this should NOT go into the bankroll yet // and must be quarantined here to prevent timing attacks LIABILITIES = SafeMath.add(LIABILITIES, msg.value); emit BuyCredits(oraclizeQueryId); } function __callback(bytes32 _queryId, string _result, bytes _proof) public { // get the game data and put into memory SlotsGameData memory data = slotsData[_queryId]; require(msg.sender == oraclize_cbAddress() && !data.paidOut && data.player != address(0) && LIABILITIES >= data.etherReceived); // if the proof has failed, immediately refund the player the original bet. if (oraclize_randomDS_proofVerify__returnCode(_queryId, _result, _proof) != 0){ if (REFUNDSACTIVE){ // set contract data slotsData[_queryId].paidOut = true; // subtract from liabilities and amount wagered, because this bet is being refunded. LIABILITIES = SafeMath.sub(LIABILITIES, data.etherReceived); // transfer the original bet back data.player.transfer(data.etherReceived); // log the refund emit Refund(_queryId, data.etherReceived); } // log the ledger proof fail emit LedgerProofFailed(_queryId); } else { // again, this block is almost identical to the previous block in the play(...) function // instead of duplicating documentation, we will just point out the changes from the other block uint256 dialsSpun; uint8 dial1; uint8 dial2; uint8 dial3; uint256[] memory logsData = new uint256[](8); uint256 payout; // must use data.credits instead of credits. for (uint8 i = 0; i < data.credits; i++){ // all dials now use _result, instead of blockhash, this is the main change, and allows Slots to // accomodate bets of any size, free of possible miner interference dialsSpun += 1; dial1 = uint8(uint(keccak256(_result, dialsSpun)) % 64); dialsSpun += 1; dial2 = uint8(uint(keccak256(_result, dialsSpun)) % 64); dialsSpun += 1; dial3 = uint8(uint(keccak256(_result, dialsSpun)) % 64); // dial 1 dial1 = getDial1Type(dial1); // dial 2 dial2 = getDial2Type(dial2); // dial 3 dial3 = getDial3Type(dial3); // determine the payout payout += determinePayout(dial1, dial2, dial3); // assembling log data if (i <= 27){ // in logsData0 logsData[0] += uint256(dial1) * uint256(2) ** (3 * ((3 * (27 - i)) + 2)); logsData[0] += uint256(dial2) * uint256(2) ** (3 * ((3 * (27 - i)) + 1)); logsData[0] += uint256(dial3) * uint256(2) ** (3 * ((3 * (27 - i)))); } else if (i <= 55){ // in logsData1 logsData[1] += uint256(dial1) * uint256(2) ** (3 * ((3 * (55 - i)) + 2)); logsData[1] += uint256(dial2) * uint256(2) ** (3 * ((3 * (55 - i)) + 1)); logsData[1] += uint256(dial3) * uint256(2) ** (3 * ((3 * (55 - i)))); } else if (i <= 83) { // in logsData2 logsData[2] += uint256(dial1) * uint256(2) ** (3 * ((3 * (83 - i)) + 2)); logsData[2] += uint256(dial2) * uint256(2) ** (3 * ((3 * (83 - i)) + 1)); logsData[2] += uint256(dial3) * uint256(2) ** (3 * ((3 * (83 - i)))); } else if (i <= 111) { // in logsData3 logsData[3] += uint256(dial1) * uint256(2) ** (3 * ((3 * (111 - i)) + 2)); logsData[3] += uint256(dial2) * uint256(2) ** (3 * ((3 * (111 - i)) + 1)); logsData[3] += uint256(dial3) * uint256(2) ** (3 * ((3 * (111 - i)))); } else if (i <= 139){ // in logsData4 logsData[4] += uint256(dial1) * uint256(2) ** (3 * ((3 * (139 - i)) + 2)); logsData[4] += uint256(dial2) * uint256(2) ** (3 * ((3 * (139 - i)) + 1)); logsData[4] += uint256(dial3) * uint256(2) ** (3 * ((3 * (139 - i)))); } else if (i <= 167){ // in logsData5 logsData[5] += uint256(dial1) * uint256(2) ** (3 * ((3 * (167 - i)) + 2)); logsData[5] += uint256(dial2) * uint256(2) ** (3 * ((3 * (167 - i)) + 1)); logsData[5] += uint256(dial3) * uint256(2) ** (3 * ((3 * (167 - i)))); } else if (i <= 195){ // in logsData6 logsData[6] += uint256(dial1) * uint256(2) ** (3 * ((3 * (195 - i)) + 2)); logsData[6] += uint256(dial2) * uint256(2) ** (3 * ((3 * (195 - i)) + 1)); logsData[6] += uint256(dial3) * uint256(2) ** (3 * ((3 * (195 - i)))); } else if (i <= 223){ // in logsData7 logsData[7] += uint256(dial1) * uint256(2) ** (3 * ((3 * (223 - i)) + 2)); logsData[7] += uint256(dial2) * uint256(2) ** (3 * ((3 * (223 - i)) + 1)); logsData[7] += uint256(dial3) * uint256(2) ** (3 * ((3 * (223 - i)))); } } // track that these spins were made DIALSSPUN += dialsSpun; // and add the amount wagered AMOUNTWAGERED = SafeMath.add(AMOUNTWAGERED, data.etherReceived); // IMPORTANT: we must change the "paidOut" to TRUE here to prevent reentrancy/other nasty effects. // this was not needed with the previous loop/code block, and is used because variables must be written into storage slotsData[_queryId].paidOut = true; // decrease LIABILITIES when the spins are made LIABILITIES = SafeMath.sub(LIABILITIES, data.etherReceived); // get the developers cut, and send the rest of the ether received to the bankroller contract uint256 developersCut = data.etherReceived / 100; DEVELOPERSFUND = SafeMath.add(DEVELOPERSFUND, developersCut); EOSBetBankrollInterface(BANKROLLER).receiveEtherFromGameAddress.value(SafeMath.sub(data.etherReceived, developersCut))(); // get the ether to be paid out, and force the bankroller contract to pay out the player uint256 etherPaidout = SafeMath.mul((data.etherReceived / data.credits), payout); EOSBetBankrollInterface(BANKROLLER).payEtherToWinner(etherPaidout, data.player); // log en event with indexed query id emit SlotsLargeBet(_queryId, logsData[0], logsData[1], logsData[2], logsData[3], logsData[4], logsData[5], logsData[6], logsData[7]); } } // HELPER FUNCTIONS TO: // calculate the result of the dials based on the hardcoded slot data: // STOPS REEL#1 REEL#2 REEL#3 /////////////////////////////////////////// // gold ether 0 // 1 // 3 // 1 // // silver ether 1 // 7 // 1 // 6 // // bronze ether 2 // 1 // 7 // 6 // // gold planet 3 // 5 // 7 // 6 // // silverplanet 4 // 9 // 6 // 7 // // bronzeplanet 5 // 9 // 8 // 6 // // ---blank--- 6 // 32 // 32 // 32 // /////////////////////////////////////////// // note that dial1 / 2 / 3 will go from mod 64 to mod 7 in this manner function getDial1Type(uint8 dial1Location) internal pure returns(uint8) { if (dial1Location == 0) { return 0; } else if (dial1Location >= 1 && dial1Location <= 7) { return 1; } else if (dial1Location == 8) { return 2; } else if (dial1Location >= 9 && dial1Location <= 13) { return 3; } else if (dial1Location >= 14 && dial1Location <= 22) { return 4; } else if (dial1Location >= 23 && dial1Location <= 31) { return 5; } else { return 6; } } function getDial2Type(uint8 dial2Location) internal pure returns(uint8) { if (dial2Location >= 0 && dial2Location <= 2) { return 0; } else if (dial2Location == 3) { return 1; } else if (dial2Location >= 4 && dial2Location <= 10) { return 2; } else if (dial2Location >= 11 && dial2Location <= 17) { return 3; } else if (dial2Location >= 18 && dial2Location <= 23) { return 4; } else if (dial2Location >= 24 && dial2Location <= 31) { return 5; } else { return 6; } } function getDial3Type(uint8 dial3Location) internal pure returns(uint8) { if (dial3Location == 0) { return 0; } else if (dial3Location >= 1 && dial3Location <= 6) { return 1; } else if (dial3Location >= 7 && dial3Location <= 12) { return 2; } else if (dial3Location >= 13 && dial3Location <= 18) { return 3; } else if (dial3Location >= 19 && dial3Location <= 25) { return 4; } else if (dial3Location >= 26 && dial3Location <= 31) { return 5; } else { return 6; } } // HELPER FUNCTION TO: // determine the payout given dial locations based on this table // hardcoded payouts data: // LANDS ON // PAYS // //////////////////////////////////////////////// // Bronze E -> Silver E -> Gold E // 5000 // // 3x Gold Ether // 1777 // // 3x Silver Ether // 250 // // 3x Bronze Ether // 250 // // Bronze P -> Silver P -> Gold P // 90 // // 3x any Ether // 70 // // 3x Gold Planet // 50 // // 3x Silver Planet // 25 // // Any Gold P & Silver P & Bronze P // 15 // // 3x Bronze Planet // 10 // // Any 3 planet type // 3 // // Any 3 gold // 3 // // Any 3 silver // 2 // // Any 3 bronze // 2 // // Blank, blank, blank // 1 // // else // 0 // //////////////////////////////////////////////// function determinePayout(uint8 dial1, uint8 dial2, uint8 dial3) internal pure returns(uint256) { if (dial1 == 6 || dial2 == 6 || dial3 == 6){ // all blank if (dial1 == 6 && dial2 == 6 && dial3 == 6) return 1; } else if (dial1 == 5){ // bronze planet -> silver planet -> gold planet if (dial2 == 4 && dial3 == 3) return 90; // one gold planet, one silver planet, one bronze planet, any order! // note: other order covered above, return 90 else if (dial2 == 3 && dial3 == 4) return 15; // all bronze planet else if (dial2 == 5 && dial3 == 5) return 10; // any three planet type else if (dial2 >= 3 && dial2 <= 5 && dial3 >= 3 && dial3 <= 5) return 3; // any three bronze else if ((dial2 == 2 || dial2 == 5) && (dial3 == 2 || dial3 == 5)) return 2; } else if (dial1 == 4){ // all silver planet if (dial2 == 4 && dial3 == 4) return 25; // one gold planet, one silver planet, one bronze planet, any order! else if ((dial2 == 3 && dial3 == 5) || (dial2 == 5 && dial3 == 3)) return 15; // any three planet type else if (dial2 >= 3 && dial2 <= 5 && dial3 >= 3 && dial3 <= 5) return 3; // any three silver else if ((dial2 == 1 || dial2 == 4) && (dial3 == 1 || dial3 == 4)) return 2; } else if (dial1 == 3){ // all gold planet if (dial2 == 3 && dial3 == 3) return 50; // one gold planet, one silver planet, one bronze planet, any order! else if ((dial2 == 4 && dial3 == 5) || (dial2 == 5 && dial3 == 4)) return 15; // any three planet type else if (dial2 >= 3 && dial2 <= 5 && dial3 >= 3 && dial3 <= 5) return 3; // any three gold else if ((dial2 == 0 || dial2 == 3) && (dial3 == 0 || dial3 == 3)) return 3; } else if (dial1 == 2){ if (dial2 == 1 && dial3 == 0) return 5000; // jackpot!!!! // all bronze ether else if (dial2 == 2 && dial3 == 2) return 250; // all some type of ether else if (dial2 >= 0 && dial2 <= 2 && dial3 >= 0 && dial3 <= 2) return 70; // any three bronze else if ((dial2 == 2 || dial2 == 5) && (dial3 == 2 || dial3 == 5)) return 2; } else if (dial1 == 1){ // all silver ether if (dial2 == 1 && dial3 == 1) return 250; // all some type of ether else if (dial2 >= 0 && dial2 <= 2 && dial3 >= 0 && dial3 <= 2) return 70; // any three silver else if ((dial2 == 1 || dial2 == 4) && (dial3 == 1 || dial3 == 4)) return 3; } else if (dial1 == 0){ // all gold ether if (dial2 == 0 && dial3 == 0) return 1777; // all some type of ether else if (dial2 >= 0 && dial2 <= 2 && dial3 >= 0 && dial3 <= 2) return 70; // any three gold else if ((dial2 == 0 || dial2 == 3) && (dial3 == 0 || dial3 == 3)) return 3; } return 0; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"newTime","type":"uint256"}],"name":"setOraclizeQueryMaxTime","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAXWIN_inTHOUSANDTHPERCENTS","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEVELOPERSFUND","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LIABILITIES","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DIALSSPUN","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"OWNER","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AMOUNTWAGERED","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"minBet","type":"uint256"}],"name":"setMinBetPerSpin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"REFUNDSACTIVE","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"myid","type":"bytes32"},{"name":"result","type":"string"}],"name":"__callback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"minBet","type":"uint256"}],"name":"setMinBetPerTx","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"slotsData","outputs":[{"name":"player","type":"address"},{"name":"paidOut","type":"bool"},{"name":"start","type":"uint256"},{"name":"etherReceived","type":"uint256"},{"name":"credits","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_queryId","type":"bytes32"},{"name":"_result","type":"string"},{"name":"_proof","type":"bytes"}],"name":"__callback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"credits","type":"uint8"}],"name":"play","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"MINBET_perSPIN","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"oraclizeQueryId","type":"bytes32"}],"name":"refund","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ORACLIZEQUERYMAXTIME","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"developer","type":"address"}],"name":"payDevelopersFund","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newMaxWinInThousandthPercents","type":"uint16"}],"name":"setMaxwin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"gasPrice","type":"uint256"}],"name":"setOraclizeQueryGasPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getMaxWin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"receivePaymentForOraclize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"BANKROLLER","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"paused","type":"bool"}],"name":"setGamePaused","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MINBET_perTX","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"bankrollAddress","type":"address"}],"name":"setBankrollerContractOnce","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"amtTokens","type":"uint256"}],"name":"ERC20Rescue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ORACLIZEGASPRICE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"INITIALGASFORORACLIZE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"GAMEPAUSED","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"active","type":"bool"}],"name":"setRefundsActive","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"gasAmt","type":"uint256"}],"name":"setInitialGasForOraclize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oraclizeQueryId","type":"bytes32"}],"name":"BuyCredits","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oraclizeQueryId","type":"bytes32"}],"name":"LedgerProofFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oraclizeQueryId","type":"bytes32"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oraclizeQueryId","type":"bytes32"},{"indexed":false,"name":"data1","type":"uint256"},{"indexed":false,"name":"data2","type":"uint256"},{"indexed":false,"name":"data3","type":"uint256"},{"indexed":false,"name":"data4","type":"uint256"},{"indexed":false,"name":"data5","type":"uint256"},{"indexed":false,"name":"data6","type":"uint256"},{"indexed":false,"name":"data7","type":"uint256"},{"indexed":false,"name":"data8","type":"uint256"}],"name":"SlotsLargeBet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"data1","type":"uint256"},{"indexed":false,"name":"data2","type":"uint256"},{"indexed":false,"name":"data3","type":"uint256"},{"indexed":false,"name":"data4","type":"uint256"},{"indexed":false,"name":"data5","type":"uint256"},{"indexed":false,"name":"data6","type":"uint256"},{"indexed":false,"name":"data7","type":"uint256"},{"indexed":false,"name":"data8","type":"uint256"}],"name":"SlotsSmallBet","type":"event"}]
Contract Creation Code
606060405234156200001057600080fd5b620000497f30000000000000000000000000000000000000000000000000000000000000006401000000006200487d620000f882021704565b620000676401dcd6500064010000000062002b616200030482021704565b6401dcd65000600f5562036ee86010556000600a819055600b5560118054615460600c5566071afd498d0000600d55662386f26fc10000600e5561014d630100000063ffff0000199092169190911761ffff1916177fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000033600160a060020a0316021790556200099a565b600054600160a060020a031615806200013357506000546200013190600160a060020a031664010000000062002cd8620004db82021704565b155b15620001555762000153600064010000000062002cdc620004df82021704565b505b600054600160a060020a03166338cc48316040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515620001ae57600080fd5b5af11515620001bc57600080fd5b5050506040518051600154600160a060020a0390811691161490506200026d57600054600160a060020a03166338cc48316040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156200023557600080fd5b5af115156200024357600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663688dcfd7826040517c010000000000000000000000000000000000000000000000000000000063ffffffff84160281527fff000000000000000000000000000000000000000000000000000000000000009091166004820152602401600060405180830381600087803b1515620002f057600080fd5b5af11515620002fe57600080fd5b50505050565b600054600160a060020a031615806200033f57506000546200033d90600160a060020a031664010000000062002cd8620004db82021704565b155b1562000361576200035f600064010000000062002cdc620004df82021704565b505b600054600160a060020a03166338cc48316040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515620003ba57600080fd5b5af11515620003c857600080fd5b5050506040518051600154600160a060020a0390811691161490506200047957600054600160a060020a03166338cc48316040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156200044157600080fd5b5af115156200044f57600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663ca6ad1e4826040517c010000000000000000000000000000000000000000000000000000000063ffffffff84160281526004810191909152602401600060405180830381600087803b1515620002f057600080fd5b3b90565b6000620004f9640100000000620036a5620004ff82021704565b92915050565b6000806200052f731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed64010000000062002cd8620004db82021704565b1115620005b15760008054600160a060020a031916731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed179055620005a860408051908101604052600b81527f6574685f6d61696e6e65740000000000000000000000000000000000000000006020820152640100000000620043ae620008df82021704565b506001620008dc565b6000620005e073c03a2615d5efaf5f49f60b7bb6583eaec212fdf164010000000062002cd8620004db82021704565b1115620006595760008054600160a060020a03191673c03a2615d5efaf5f49f60b7bb6583eaec212fdf1179055620005a860408051908101604052600c81527f6574685f726f707374656e3300000000000000000000000000000000000000006020820152640100000000620043ae620008df82021704565b60006200068873b7a07bcf2ba2f2703b24c0691b5278999c59ac7e64010000000062002cd8620004db82021704565b1115620007015760008054600160a060020a03191673b7a07bcf2ba2f2703b24c0691b5278999c59ac7e179055620005a860408051908101604052600981527f6574685f6b6f76616e00000000000000000000000000000000000000000000006020820152640100000000620043ae620008df82021704565b60006200073073146500cfd35b22e4a392fe0adc06de1a1368ed4864010000000062002cd8620004db82021704565b1115620007a95760008054600160a060020a03191673146500cfd35b22e4a392fe0adc06de1a1368ed48179055620005a860408051908101604052600b81527f6574685f72696e6b6562790000000000000000000000000000000000000000006020820152640100000000620043ae620008df82021704565b6000620007d8736f485c8bf6fc43ea212e93bbf8ce046c7f1cb47564010000000062002cd8620004db82021704565b11156200080e575060008054600160a060020a031916736f485c8bf6fc43ea212e93bbf8ce046c7f1cb4751790556001620008dc565b60006200083d7320e12a1f859b3feae5fb2a0a32c18f5a65555bbf64010000000062002cd8620004db82021704565b111562000873575060008054600160a060020a0319167320e12a1f859b3feae5fb2a0a32c18f5a65555bbf1790556001620008dc565b6000620008a27351efaf4c8b3c9afbd5ab9f4bbc82784ab6ef8faa64010000000062002cd8620004db82021704565b1115620008d8575060008054600160a060020a0319167351efaf4c8b3c9afbd5ab9f4bbc82784ab6ef8faa1790556001620008dc565b5060005b90565b6002818051620008f4929160200190620008f8565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200093b57805160ff19168380011785556200096b565b828001600101855582156200096b579182015b828111156200096b5782518255916020019190600101906200094e565b50620009799291506200097d565b5090565b620008dc91905b8082111562000979576000815560010162000984565b614a2e80620009aa6000396000f3006060604052600436106101875763ffffffff60e060020a60003504166301f9a0aa811461018c57806306784b81146101a457806307efbf2b146101ce57806309b481b0146101f357806310d7b90314610206578063117803e31461021957806313d73a0814610248578063150d62771461025b5780631fbd9a0b1461027157806327dc297e146102985780633119255c146102ee5780633792eb981461030457806338bbfa501461035757806353a04b05146103ef5780635e9a31fb146103fd5780637249fbb6146104105780637ea17a1d146104265780638579c10e146104395780638a1fde4b146104585780638aa19ef71461047257806391a1f16a14610488578063a3b9b8d11461049b578063aefbbf2a146104a3578063b5c14adb146104b6578063ba2d5c88146104ce578063cc783c5e146104e1578063dab7882014610500578063dbfc74cb14610522578063ef2e732114610535578063f2fde38b14610548578063f331020c14610567578063fb87eb0b1461057a578063fc0e64de14610592575b600080fd5b341561019757600080fd5b6101a26004356105a8565b005b34156101af57600080fd5b6101b76105d0565b60405161ffff909116815260200160405180910390f35b34156101d957600080fd5b6101e16105da565b60405190815260200160405180910390f35b34156101fe57600080fd5b6101e16105e0565b341561021157600080fd5b6101e16105e6565b341561022457600080fd5b61022c6105ec565b604051600160a060020a03909116815260200160405180910390f35b341561025357600080fd5b6101e1610603565b341561026657600080fd5b6101a2600435610609565b341561027c57600080fd5b610284610640565b604051901515815260200160405180910390f35b34156102a357600080fd5b6101a2600480359060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065095505050505050565b34156102f957600080fd5b6101a2600435610682565b341561030f57600080fd5b61031a6004356106b9565b604051600160a060020a0390951685529215156020850152604080850192909252606084015260ff909116608083015260a0909101905180910390f35b341561036257600080fd5b6101a2600480359060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405281815292919060208401838380828437509496506106f795505050505050565b6101a260ff6004351661124f565b341561040857600080fd5b6101e1611488565b341561041b57600080fd5b6101a260043561148e565b341561043157600080fd5b6101e1611652565b341561044457600080fd5b6101a2600160a060020a0360043516611658565b341561046357600080fd5b6101a261ffff600435166116b1565b341561047d57600080fd5b6101a2600435611700565b341561049357600080fd5b6101e1611734565b6101a26117b2565b34156104ae57600080fd5b61022c6117cf565b34156104c157600080fd5b6101a260043515156117de565b34156104d957600080fd5b6101e161181d565b34156104ec57600080fd5b6101a2600160a060020a0360043516611823565b341561050b57600080fd5b6101a2600160a060020a03600435166024356118de565b341561052d57600080fd5b6101e1611970565b341561054057600080fd5b6101e1611976565b341561055357600080fd5b6101a2600160a060020a036004351661197c565b341561057257600080fd5b6102846119da565b341561058557600080fd5b6101a260043515156119e9565b341561059d57600080fd5b6101a2600435611a2a565b60115433600160a060020a0390811664010000000090920416146105cb57600080fd5b600c55565b60115461ffff1681565b60095481565b60085481565b600b5481565b6011546401000000009004600160a060020a031681565b600a5481565b60115433600160a060020a039081166401000000009092041614801561063057506103e881115b151561063b57600080fd5b600d55565b6011546301000000900460ff1681565b61067e828260006040518059106106645750595b818152601f19601f830116810160200160405290506106f7565b5050565b60115433600160a060020a03908116640100000000909204161480156106a957506103e881115b15156106b457600080fd5b600e55565b6007602052600090815260409020805460018201546002830154600390930154600160a060020a0383169360ff60a060020a90940484169390911685565b6106ff614778565b60008060008061070d6147a6565b60008981526007602052604080822082918291829160a0905190810160409081528254600160a060020a038116835260ff60a060020a909104811615156020840152600184015491830191909152600283015460608301526003909201549091166080820152995061077d611a52565b600160a060020a031633600160a060020a031614801561079f57508960200151155b80156107b6575060008a51600160a060020a031614155b80156107c85750896060015160085410155b15156107d357600080fd5b6107de8d8d8d611bc9565b60ff16156108df576011546301000000900460ff16156108ad5760008d8152600760205260409020805474ff0000000000000000000000000000000000000000191660a060020a1790556008546108399060608c0151611cf3565b6008558951600160a060020a03166108fc8b606001519081150290604051600060405180830381858888f19350505050151561087457600080fd5b8c7fdda15e30b719d5c232faad22f4c2c1e8994336c026868ed0d3bc4aac71977abb60608c015160405190815260200160405180910390a25b8c7f2576aa524eff2f518901d6458ad267a59debacb7bf8700998dba20313f17dce660405160405180910390a2611240565b60086040518059106108ee5750595b90808252806020026020018201604052509450600092505b896080015160ff168360ff161015610fb35760018901985060408c8a6040518083805190602001908083835b602083106109515780518252601f199092019160209182019101610932565b6001836020036101000a0380198251168184511617909252505050919091019283525050602001905060405190819003902081151561098c57fe5b06975060018901985060408c8a6040518083805190602001908083835b602083106109c85780518252601f1990920191602091820191016109a9565b6001836020036101000a03801982511681845116179092525050509190910192835250506020019050604051908190039020811515610a0357fe5b06965060018901985060408c8a6040518083805190602001908083835b60208310610a3f5780518252601f199092019160209182019101610a20565b6001836020036101000a03801982511681845116179092525050509190910192835250506020019050604051908190039020811515610a7a57fe5b069550610a8688611d05565b9750610a9187611dca565b9650610a9c86611e95565b9550610aa9888888611f5f565b90930192601b60ff841611610b5c5782601b0360030260020160030260ff1660020a8860ff160285600081518110610add57fe5b906020019060200201818151019150818152505082601b0360030260010160030260ff1660020a8760ff160285600081518110610b1657fe5b90602001906020020181815101905250601b83900360090260ff90811660020a9087160285600081518110610b4757fe5b90602001906020020181815101905250610fa8565b603760ff841611610bf6578260370360030260020160030260ff1660020a8860ff160285600181518110610b8c57fe5b90602001906020020181815101915081815250508260370360030260010160030260ff1660020a8760ff160285600181518110610bc557fe5b90602001906020020181815101905250603783900360090260ff90811660020a9087160285600181518110610b4757fe5b605360ff841611610c95578260530360030260020160030260ff1660020a8860ff160285600281518110610c2657fe5b90602001906020020181815101915081815250508260530360030260010160030260ff1660020a8760ff160285600281518110610c5f57fe5b90602001906020020181815101915081815250508260530360030260030260ff1660020a8660ff160285600281518110610b4757fe5b606f60ff841611610d2f5782606f0360030260020160030260ff1660020a8860ff160285600381518110610cc557fe5b906020019060200201818151019150818152505082606f0360030260010160030260ff1660020a8760ff160285600381518110610cfe57fe5b90602001906020020181815101905250606f83900360090260ff90811660020a9087160285600381518110610b4757fe5b608b60ff841611610dc95782608b0360030260020160030260ff1660020a8860ff160285600481518110610d5f57fe5b906020019060200201818151019150818152505082608b0360030260010160030260ff1660020a8760ff160285600481518110610d9857fe5b90602001906020020181815101905250608b83900360090260ff90811660020a9087160285600481518110610b4757fe5b60a760ff841611610e63578260a70360030260020160030260ff1660020a8860ff160285600581518110610df957fe5b90602001906020020181815101915081815250508260a70360030260010160030260ff1660020a8760ff160285600581518110610e3257fe5b9060200190602002018181510190525060a783900360090260ff90811660020a9087160285600581518110610b4757fe5b60c360ff841611610efd578260c30360030260020160030260ff1660020a8860ff160285600681518110610e9357fe5b90602001906020020181815101915081815250508260c30360030260010160030260ff1660020a8760ff160285600681518110610ecc57fe5b9060200190602002018181510190525060c383900360090260ff90811660020a9087160285600681518110610b4757fe5b60df60ff841611610fa8578260df0360030260020160030260ff1660020a8860ff160285600781518110610f2d57fe5b90602001906020020181815101915081815250508260df0360030260010160030260ff1660020a8760ff160285600781518110610f6657fe5b9060200190602002018181510190525060df83900360090260ff90811660020a9087160285600781518110610f9757fe5b906020019060200201818151019052505b600190920191610906565b600b80548a019055600a54610fcc9060608c0151612490565b600a5560008d8152600760205260409020805474ff0000000000000000000000000000000000000000191660a060020a1790556008546110109060608c0151611cf3565b600855606460608b015181151561102357fe5b04915061103260095483612490565b600955601254600160a060020a031663fbe00e8e61105460608d015185611cf3565b6040518263ffffffff1660e060020a0281526004016000604051808303818588803b151561108157600080fd5b5af1151561108e57600080fd5b505050506110b28a6080015160ff168b606001518115156110ab57fe5b04856124aa565b601254909150600160a060020a031663becd0580828c5160405160e060020a63ffffffff85160281526004810192909252600160a060020a03166024820152604401600060405180830381600087803b151561110d57600080fd5b5af1151561111a57600080fd5b508e91507fc97a66505c1c68fd69c7d907e99a861eb4cf9a33460059bee6f6ec5a9e67793190508660008151811061114e57fe5b906020019060200201518760018151811061116557fe5b906020019060200201518860028151811061117c57fe5b906020019060200201518960038151811061119357fe5b906020019060200201518a6004815181106111aa57fe5b906020019060200201518b6005815181106111c157fe5b906020019060200201518c6006815181106111d857fe5b906020019060200201518d6007815181106111ef57fe5b90602001906020020151604051808981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019850505050505050505060405180910390a25b50505050505050505050505050565b60008060008360ff163481151561126257fe5b601154919004935062010000900460ff161580156112825750600e543410155b80156112905750600d548310155b801561129f575060008460ff16115b80156112af575060e08460ff1611155b80156112cd57506112be611734565b6112ca846113886124aa565b11155b15156112d857600080fd5b60105460125460ff8616610cc6029091019250600160a060020a03166366479c0861133660408051908101604052600681527f72616e646f6d00000000000000000000000000000000000000000000000000006020820152856124d5565b60405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b151561136c57600080fd5b5af1151561137957600080fd5b5050506113896000601e846126c3565b905060a06040519081016040908152600160a060020a033316825260006020808401829052428385015234606085015260ff88166080850152848252600790522081518154600160a060020a031916600160a060020a03919091161781556020820151815490151560a060020a0274ff00000000000000000000000000000000000000001990911617815560408201518160010155606082015181600201556080820151600391909101805460ff191660ff909216919091179055506008546114529034612490565b600855807fcfd1f319fe9af0531e626b618361fcb41e067cbc1858a3f6e7a2ec24182eca9f60405160405180910390a250505050565b600d5481565b611496614778565b600082815260076020526040908190209060a0905190810160409081528254600160a060020a038116835260ff60a060020a9091048116151560208401526001840154918301918252600284015460608401526003909301549092166080820152600c549092509061150a90429051611cf3565b1015801561154a575060115433600160a060020a0390811664010000000090920416148061154a57508051600160a060020a031633600160a060020a0316145b801561155857508060200151155b801561156a5750600854816060015111155b801561157a575060008160600151115b801561158f57506011546301000000900460ff165b151561159a57600080fd5b6000828152600760205260409020805474ff0000000000000000000000000000000000000000191660a060020a1790556008546115db906060830151611cf3565b6008558051600160a060020a03166108fc82606001519081150290604051600060405180830381858888f19350505050151561161657600080fd5b817fdda15e30b719d5c232faad22f4c2c1e8994336c026868ed0d3bc4aac71977abb606083015160405190815260200160405180910390a25050565b600c5481565b60125460009033600160a060020a0390811691161461167657600080fd5b50600980546000909155600160a060020a03821681156108fc0282604051600060405180830381858888f19350505050151561067e57600080fd5b60115433600160a060020a03908116640100000000909204161480156116dd575061014d8161ffff1611155b15156116e857600080fd5b6011805461ffff191661ffff92909216919091179055565b60115433600160a060020a03908116640100000000909204161461172357600080fd5b600f81905561173181612b61565b50565b6012546000906103e8906117a290600160a060020a0316630d1fce426040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561177e57600080fd5b5af1151561178b57600080fd5b505050604051805160115490915061ffff166124aa565b8115156117ab57fe5b0490505b90565b60125433600160a060020a039081169116146117cd57600080fd5b565b601254600160a060020a031681565b60115433600160a060020a03908116640100000000909204161461180157600080fd5b60118054911515620100000262ff000019909216919091179055565b600e5481565b60115433600160a060020a03908116640100000000909204161480156118525750601254600160a060020a0316155b151561185d57600080fd5b80600160a060020a0316630d1fce426040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561189a57600080fd5b5af115156118a757600080fd5b5050506040518051151590506118bc57600080fd5b60128054600160a060020a031916600160a060020a0392909216919091179055565b60115433600160a060020a03908116640100000000909204161461190157600080fd5b81600160a060020a031663a9059cbb338360405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b151561195557600080fd5b5af1151561196257600080fd5b505050604051805150505050565b600f5481565b60105481565b60115433600160a060020a03908116640100000000909204161461199f57600080fd5b60118054600160a060020a039092166401000000000277ffffffffffffffffffffffffffffffffffffffff0000000019909216919091179055565b60115462010000900460ff1681565b60115433600160a060020a039081166401000000009092041614611a0c57600080fd5b6011805491151563010000000263ff00000019909216919091179055565b60115433600160a060020a039081166401000000009092041614611a4d57600080fd5b601055565b60008054600160a060020a03161580611a7d5750600054611a7b90600160a060020a0316612cd8565b155b15611a8e57611a8c6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611acd57600080fd5b5af11515611ada57600080fd5b5050506040518051600154600160a060020a039081169116149050611b6f57600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611b3857600080fd5b5af11515611b4557600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663c281d19e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611bae57600080fd5b5af11515611bbb57600080fd5b505050604051805191505090565b60008082600081518110611bd957fe5b016020015160f860020a900460f860020a02600160f860020a0319167f4c00000000000000000000000000000000000000000000000000000000000000141580611c6b575082600181518110611c2b57fe5b016020015160f860020a900460f860020a02600160f860020a0319167f500000000000000000000000000000000000000000000000000000000000000014155b80611cb3575082600281518110611c7e57fe5b01602001517fff0000000000000000000000000000000000000000000000000000000000000060f860020a9182900482021614155b15611cc15760019150611ceb565b611cd4838686611ccf612cec565b612d94565b9050801515611ce65760029150611ceb565b600091505b509392505050565b600082821115611cff57fe5b50900390565b600060ff82161515611d1957506000611dc5565b60018260ff1610158015611d31575060078260ff1611155b15611d3e57506001611dc5565b8160ff1660081415611d5257506002611dc5565b60098260ff1610158015611d6a5750600d8260ff1611155b15611d7757506003611dc5565b600e8260ff1610158015611d8f575060168260ff1611155b15611d9c57506004611dc5565b60178260ff1610158015611db45750601f8260ff1611155b15611dc157506005611dc5565b5060065b919050565b6000808260ff1610158015611de3575060028260ff1611155b15611df057506000611dc5565b8160ff1660031415611e0457506001611dc5565b60048260ff1610158015611e1c5750600a8260ff1611155b15611e2957506002611dc5565b600b8260ff1610158015611e41575060118260ff1611155b15611e4e57506003611dc5565b60128260ff1610158015611e66575060178260ff1611155b15611e7357506004611dc5565b60188260ff1610158015611db45750601f60ff831611611dc157506005611dc5565b600060ff82161515611ea957506000611dc5565b60018260ff1610158015611ec1575060068260ff1611155b15611ece57506001611dc5565b60078260ff1610158015611ee65750600c8260ff1611155b15611ef357506002611dc5565b600d8260ff1610158015611f0b575060128260ff1611155b15611f1857506003611dc5565b60138260ff1610158015611f30575060198260ff1611155b15611f3d57506004611dc5565b601a8260ff1610158015611db45750601f60ff831611611dc157506005611dc5565b60008360ff1660061480611f7657508260ff166006145b80611f8457508160ff166006145b15611fc0578360ff166006148015611f9f57508260ff166006145b8015611fae57508160ff166006145b15611fbb57506001612489565b612485565b8360ff16600514156120b8578260ff166004148015611fe257508160ff166003145b15611fef5750605a612489565b8260ff16600314801561200557508160ff166004145b156120125750600f612489565b8260ff16600514801561202857508160ff166005145b156120355750600a612489565b60038360ff161015801561204d575060058360ff1611155b801561205d575060038260ff1610155b801561206d575060058260ff1611155b1561207a57506003612489565b8260ff166002148061208f57508260ff166005145b80156120ab57508160ff16600214806120ab57508160ff166005145b15611fbb57506002612489565b8360ff16600414156121a8578260ff1660041480156120da57508160ff166004145b156120e757506019612489565b8260ff1660031480156120fd57508160ff166005145b8061211957508260ff16600514801561211957508160ff166003145b156121265750600f612489565b60038360ff161015801561213e575060058360ff1611155b801561214e575060038260ff1610155b801561215e575060058260ff1611155b1561216b57506003612489565b8260ff166001148061218057508260ff166004145b80156120ab57508160ff16600114806120ab57508160ff1660041415611fbb57506002612489565b8360ff1660031415612295578260ff1660031480156121ca57508160ff166003145b156121d757506032612489565b8260ff1660041480156121ed57508160ff166005145b8061220957508260ff16600514801561220957508160ff166004145b156122165750600f612489565b60038360ff161015801561222e575060058360ff1611155b801561223e575060038260ff1610155b801561224e575060058260ff1611155b1561225b57506003612489565b60ff8316158061226e57508260ff166003145b8015612288575060ff8216158061228857508160ff166003145b15611fbb57506003612489565b8360ff166002141561232b578260ff1660011480156122b5575060ff8216155b156122c35750611388612489565b8260ff1660021480156122d957508160ff166002145b156122e6575060fa612489565b60008360ff16101580156122fe575060028360ff1611155b801561230e575060008260ff1610155b801561231e575060028260ff1611155b1561207a57506046612489565b8360ff16600114156123dc578260ff16600114801561234d57508160ff166001145b1561235a575060fa612489565b60008360ff1610158015612372575060028360ff1611155b8015612382575060008260ff1610155b8015612392575060028260ff1611155b1561239f57506046612489565b8260ff16600114806123b457508260ff166004145b801561228857508160ff166001148061228857508160ff1660041415611fbb57506003612489565b60ff841615156124855760ff83161580156123f8575060ff8216155b1561240657506106f1612489565b60008360ff161015801561241e575060028360ff1611155b801561242e575060008260ff1610155b801561243e575060028260ff1611155b1561244b57506046612489565b60ff8316158061245e57508260ff166003145b8015612478575060ff8216158061247857508160ff166003145b1561248557506003612489565b5060005b9392505050565b60008282018381101561249f57fe5b8091505b5092915050565b6000808315156124bd57600091506124a3565b508282028284828115156124cd57fe5b041461249f57fe5b60008054600160a060020a0316158061250057506000546124fe90600160a060020a0316612cd8565b155b156125115761250f6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561255057600080fd5b5af1151561255d57600080fd5b5050506040518051600154600160a060020a0390811691161490506125f257600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156125bb57600080fd5b5af115156125c857600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a0316632ef3accc84846040518363ffffffff1660e060020a0281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561265a578082015183820152602001612642565b50505050905090810190601f1680156126875780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b15156126a657600080fd5b5af115156126b357600080fd5b5050506040518051949350505050565b60006126cd6147a6565b6126d56147a6565b6126dd6147a6565b60006126e76147a6565b6126ef6147a6565b6126f76147b8565b60006127016147a6565b60008c118015612712575060208c11155b151561271d57600080fd5b600a8d029c5060016040518059106127325750595b818152601f19601f8301168101602001604052905098508b60f860020a028960008151811061275d57fe5b906020010190600160f860020a031916908160001a90535060206040518059106127845750595b818152601f19601f83011681016020016040529050975060206040518059106127aa5750595b818152601f19601f8301168101602001604052905096506127c96132ee565b95506020885242411860014303401860208901526020875285602088015260206040518059106127f65750595b818152601f19601f8301168101602001604052905094508c602086015260086040518059106128225750595b818152601f19601f830116810160200160405290509350612849856018600887600061344a565b506080604051908101604052808981526020018a81526020018881526020018681525092506128ac60408051908101604052600681527f72616e646f6d00000000000000000000000000000000000000000000000000006020820152848d61349f565b915060086040518059106128bd5750595b8181526020601f909201601f191681018201604052915084015160f860020a810460278301537e01000000000000000000000000000000000000000000000000000000000000810460268301537d0100000000000000000000000000000000000000000000000000000000008104602583015360e060020a810460248301537b01000000000000000000000000000000000000000000000000000000810460238301537a010000000000000000000000000000000000000000000000000000810460228301537901000000000000000000000000000000000000000000000000008104602183015378010000000000000000000000000000000000000000000000008104602083015350612b5182826020860151600287516040518082805190602001908083835b60208310612a045780518252601f1990920191602091820191016129e5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af11515612a4257600080fd5b50506040518051905060408801516040518085805190602001908083835b60208310612a7f5780518252601f199092019160209182019101612a60565b6001836020036101000a038019825116818451161790925250505091909101905084805190602001908083835b60208310612acb5780518252601f199092019160209182019101612aac565b6001836020036101000a038019825116818451161790925250505091909101848152602001905082805190602001908083835b60208310612b1d5780518252601f199092019160209182019101612afe565b6001836020036101000a03801982511681845116179092525050509190910195506040945050505050518091039020613693565b509b9a5050505050505050505050565b600054600160a060020a03161580612b8b5750600054612b8990600160a060020a0316612cd8565b155b15612b9c57612b9a6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612bdb57600080fd5b5af11515612be857600080fd5b5050506040518051600154600160a060020a039081169116149050612c7d57600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612c4657600080fd5b5af11515612c5357600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663ca6ad1e48260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515612cc557600080fd5b5af11515612cd257600080fd5b50505050565b3b90565b6000612ce66136a5565b92915050565b612cf46147a6565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612d8a5780601f10612d5f57610100808354040283529160200191612d8a565b820191906000526020600020905b815481529060010190602001808311612d6d57829003601f168201915b5050505050905090565b600080612d9f6147a6565b612da76147a6565b612daf6147a6565b612db76147a6565b600080612dc26147a6565b8c604581518110612dcf57fe5b016020015160f860020a9081900481020460660197506020604051805910612df45750595b818152601f19601f830116810160200160405290509650612e1a8d8960208a600061344a565b5060028a8d6040518083805190602001908083835b60208310612e4e5780518252601f199092019160209182019101612e2f565b6001836020036101000a038019825116818451161790925250505091909101928352505060209081019150604051808303816000865af11515612e9057600080fd5b505060405180519050604051908152602001604051908190039020876040518082805190602001908083835b60208310612edb5780518252601f199092019160209182019101612ebc565b6001836020036101000a038019825116818451161790925250505091909101925060409150505190819003902014612f1657600098506132de565b8c604a890181518110612f2557fe5b016020015160f860020a900460f860020a0260f860020a9004600201604051805910612f4e5750595b818152601f19601f830116810160200160405290509550612f778d89604901885189600061344a565b506130226002876040518082805190602001908083835b60208310612fad5780518252601f199092019160209182019101612f8e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af11515612feb57600080fd5b5050604051805190508c8f60288c018151811061300457fe5b016020015160f860020a900460f860020a0260f860020a90046139c9565b151561303157600098506132de565b60296040518059106130405750595b818152601f19601f8301168101602001604052905094506130698d89602001602988600061344a565b50604080518059106130785750595b818152601f19601f8301168101602001604052905093508551886020016029010160410192506130b08d60408503604087600061344a565b506002846040518082805190602001908083835b602083106130e35780518252601f1990920191602091820191016130c4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af1151561312157600080fd5b505060405180519050915084826040518083805190602001908083835b6020831061315d5780518252601f19909201916020918201910161313e565b6001836020036101000a0380198251168184511617909252505050919091019283525050602001905060405190819003902060008d81526003602052604090205414156131b85760008c8152600360205260408120556131c1565b600098506132de565b60496040518059106131d05750595b818152601f19601f8301168101602001604052905090506131f68d89604984600061344a565b5061327a6002826040518082805190602001908083835b6020831061322c5780518252601f19909201916020918201910161320d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af1151561326a57600080fd5b5050604051805190508786613a4f565b151561328957600098506132de565b60008281526004602052604090205460ff1615156132c9576132ab8d84613c68565b6000838152600460205260409020805460ff19169115159190911790555b60008281526004602052604090205460ff1698505b5050505050505050949350505050565b60008054600160a060020a03161580613319575060005461331790600160a060020a0316612cd8565b155b1561332a576133286000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561336957600080fd5b5af1151561337657600080fd5b5050506040518051600154600160a060020a03908116911614905061340b57600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156133d457600080fd5b5af115156133e157600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663abaa5f3e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611bae57600080fd5b6134526147a6565b838201600080828651101561346657600080fd5b505060208087019084015b86886020010182101561349257818901518682015260209182019101613471565b5093979650505050505050565b60006134a96147a6565b600054600160a060020a031615806134d357506000546134d190600160a060020a0316612cd8565b155b156134e4576134e26000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561352357600080fd5b5af1151561353057600080fd5b5050506040518051600154600160a060020a0390811691161490506135c557600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561358e57600080fd5b5af1151561359b57600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b60046040518059106135d45750595b90808252806020026020018201604052801561360a57816020015b6135f76147a6565b8152602001906001900390816135ef5790505b50905083518160008151811061361c57fe5b6020908102909101015283600160200201518160018151811061363b57fe5b602090810291909101015260408401518160028151811061365857fe5b602090810291909101015260608401518160038151811061367557fe5b6020908102909101015261368a85828561404a565b95945050505050565b60009182526003602052604090912055565b6000806136c5731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed612cd8565b11156137355760008054600160a060020a031916731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed17905561372d60408051908101604052600b81527f6574685f6d61696e6e657400000000000000000000000000000000000000000060208201526143ae565b5060016117af565b600061375473c03a2615d5efaf5f49f60b7bb6583eaec212fdf1612cd8565b11156137bc5760008054600160a060020a03191673c03a2615d5efaf5f49f60b7bb6583eaec212fdf117905561372d60408051908101604052600c81527f6574685f726f707374656e33000000000000000000000000000000000000000060208201526143ae565b60006137db73b7a07bcf2ba2f2703b24c0691b5278999c59ac7e612cd8565b11156138435760008054600160a060020a03191673b7a07bcf2ba2f2703b24c0691b5278999c59ac7e17905561372d60408051908101604052600981527f6574685f6b6f76616e000000000000000000000000000000000000000000000060208201526143ae565b600061386273146500cfd35b22e4a392fe0adc06de1a1368ed48612cd8565b11156138ca5760008054600160a060020a03191673146500cfd35b22e4a392fe0adc06de1a1368ed4817905561372d60408051908101604052600b81527f6574685f72696e6b65627900000000000000000000000000000000000000000060208201526143ae565b60006138e9736f485c8bf6fc43ea212e93bbf8ce046c7f1cb475612cd8565b111561391d575060008054600160a060020a031916736f485c8bf6fc43ea212e93bbf8ce046c7f1cb47517905560016117af565b600061393c7320e12a1f859b3feae5fb2a0a32c18f5a65555bbf612cd8565b1115613970575060008054600160a060020a0319167320e12a1f859b3feae5fb2a0a32c18f5a65555bbf17905560016117af565b600061398f7351efaf4c8b3c9afbd5ab9f4bbc82784ab6ef8faa612cd8565b11156139c3575060008054600160a060020a0319167351efaf4c8b3c9afbd5ab9f4bbc82784ab6ef8faa17905560016117af565b50600090565b6000600181838551146139db57600080fd5b5060005b83811015613a42578481815181106139f357fe5b016020015160f860020a900460f860020a02600160f860020a0319168682602081101515613a1d57fe5b1a60f860020a02600160f860020a031916141515613a3a57600091505b6001016139df565b8192505b50509392505050565b6000806000806000613a5f6147a6565b6000613a696147a6565b6020604051805910613a785750595b8181526020601f909201601f19168101820160405293508a600381518110613a9c57fe5b016020015160f860020a900460f860020a0260f860020a9004036004019150613aca8a83602086600061344a565b92506020604051805910613adb5750595b818152601f19601f830116810160200160405290509050602282019150613b338a60208c6001860381518110613b0d57fe5b016020015160f860020a900460f860020a0260f860020a9004038401602084600061344a565b90506020830151945060208101519350613b508b601b87876143c1565b9097509550600160a060020a038616896040518082805190602001908083835b60208310613b8f5780518252601f199092019160209182019101613b70565b6001836020036101000a0380198251168184511617909252505050919091019250604091505051908190039020600160a060020a03161415613bd45760019750613c5a565b613be18b601c87876143c1565b9097509550600160a060020a038616896040518082805190602001908083835b60208310613c205780518252601f199092019160209182019101613c01565b6001836020036101000a0380198251168184511617909252505050919091019250604091505051908190039020600160a060020a03161497505b505050505050509392505050565b600080613c736147a6565b613c7b6147a6565b613c836147a6565b613c8b6147a6565b613c936147a6565b613c9b6147a6565b613ca36147a6565b8a8a60010181518110613cb257fe5b016020015160f860020a900460f860020a0260f860020a9004600201604051805910613cdb5750595b818152601f19601f830116810160200160405290509650613d018b8b89518a600061344a565b5060408051805910613d105750595b818152601f19601f830116810160200160405290509550613d378b6004604089600061344a565b506062604051805910613d475750595b818152601f19601f83011681016020016040529050945060f860020a85600081518110613d7057fe5b906020010190600160f860020a031916908160001a905350613d9a8b60418c03604188600161344a565b506040805190810160405280602081526020017ffd94fa71bc0ba10d39d464d0d8f465efeef0a2764e3887fcc9df41ded20f505c8152509350613de3846000602088604261344a565b50613e676002866040518082805190602001908083835b60208310613e195780518252601f199092019160209182019101613dfa565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af11515613e5757600080fd5b5050604051805190508888613a4f565b9750871515613e79576000985061403c565b606060405190810160405280604081526020017f7fb956469c5c9b89840d55b43537e66a98dd4811ea0a27224272c2e5622911e881526020017f537a2f8e86a46baec82864e98dd01e9ccc2f8bc5dfc9cbe5a91a290498dd96e481525092506042604051805910613ee75750595b818152601f19601f8301168101602001604052905091507ffe0000000000000000000000000000000000000000000000000000000000000082600081518110613f2c57fe5b906020010190600160f860020a031916908160001a905350613f548b6003604185600161344a565b508a604581518110613f6257fe5b016020015160f860020a900460f860020a0260f860020a9004600201604051805910613f8b5750595b818152601f19601f830116810160200160405290509050613fb28b6044835184600061344a565b506140366002836040518082805190602001908083835b60208310613fe85780518252601f199092019160209182019101613fc9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af1151561402657600080fd5b5050604051805190508285613a4f565b97508798505b505050505050505092915050565b6000806140556147a6565b600054600160a060020a0316158061407f575060005461407d90600160a060020a0316612cd8565b155b156140905761408e6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156140cf57600080fd5b5af115156140dc57600080fd5b5050506040518051600154600160a060020a03908116911614905061417157600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561413a57600080fd5b5af1151561414757600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a0316632ef3accc87866040518363ffffffff1660e060020a0281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b838110156141d95780820151838201526020016141c1565b50505050905090810190601f1680156142065780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b151561422557600080fd5b5af1151561423257600080fd5b5050506040518051925050670de0b6b3a76400003a85020182111561425a5760009250613a46565b61426385614401565b600154909150600160a060020a031663c55c1cb68360008985896040518663ffffffff1660e060020a028152600401808581526020018060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156142dc5780820151838201526020016142c4565b50505050905090810190601f1680156143095780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561433f578082015183820152602001614327565b50505050905090810190601f16801561436c5780820380516001836020036101000a031916815260200191505b5096505050505050506020604051808303818588803b151561438d57600080fd5b5af1151561439a57600080fd5b505050506040518051979650505050505050565b600281805161067e9291602001906147e5565b60008060008060405188815287602082015286604082015285606082015260208160808360006001610bb8f1925080519299929850919650505050505050565b6144096147a6565b6000806144146147a6565b60008060006144216147a6565b60008060008b519950600098508960405180591061443c5750595b90808252806020026020018201604052801561447257816020015b61445f6147a6565b8152602001906001900390816144575790505b509750600096505b898710156144ff578b878151811061448e57fe5b906020019060200201518888815181106144a457fe5b60209081029091010152601760018989815181106144be57fe5b9060200190602002015151038115156144d357fe5b048888815181106144e057fe5b906020019060200201515101989098016003019760019096019561447a565b600198909801976000955060808a0194508860405180591061451e5750595b818152601f19601f8301168101602001604052905093505b6001869011156145885760f860020a8502866001811061455257fe5b1a60f860020a0284878151811061456557fe5b906020010190600160f860020a031916908160001a905350600190950194614536565b600096505b89871015614768577f5f000000000000000000000000000000000000000000000000000000000000008487815181106145c257fe5b906020010190600160f860020a031916908160001a905350600190950194600092505b8787815181106145f157fe5b9060200190602002015151831015614714576017830615156146ad5760188389898151811061461c57fe5b906020019060200201515103101561464c578288888151811061463b57fe5b90602001906020020151510361464f565b60175b60400191508590505b808603600111156146ad5760f860020a82028187036001811061467757fe5b1a60f860020a0284878151811061468a57fe5b906020010190600160f860020a031916908160001a905350600190950194614658565b8787815181106146b957fe5b9060200190602002015183815181106146ce57fe5b016020015160f860020a900460f860020a028487815181106146ec57fe5b906020010190600160f860020a031916908160001a90535060019586019592909201916145e5565b7fff0000000000000000000000000000000000000000000000000000000000000084878151811061474157fe5b906020010190600160f860020a031916908160001a9053506001968701969095019461458d565b50919a9950505050505050505050565b60a0604051908101604090815260008083526020830181905290820181905260608201819052608082015290565b60206040519081016040526000815290565b60806040519081016040526004815b6147cf6147a6565b8152602001906001900390816147c75790505090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061482657805160ff1916838001178555614853565b82800160010185558215614853579182015b82811115614853578251825591602001919060010190614838565b5061485f929150614863565b5090565b6117af91905b8082111561485f5760008155600101614869565b600054600160a060020a031615806148a757506000546148a590600160a060020a0316612cd8565b155b156148b8576148b66000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156148f757600080fd5b5af1151561490457600080fd5b5050506040518051600154600160a060020a03908116911614905061499957600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561496257600080fd5b5af1151561496f57600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663688dcfd78260405160e060020a63ffffffff84160281527fff000000000000000000000000000000000000000000000000000000000000009091166004820152602401600060405180830381600087803b1515612cc557600080fd00a165627a7a723058202d48f2cf6e8bfcc89fb1b8028c0e9f3ac99194db8d859ddd6bcf058cdfd9d4620029
Deployed Bytecode
0x6060604052600436106101875763ffffffff60e060020a60003504166301f9a0aa811461018c57806306784b81146101a457806307efbf2b146101ce57806309b481b0146101f357806310d7b90314610206578063117803e31461021957806313d73a0814610248578063150d62771461025b5780631fbd9a0b1461027157806327dc297e146102985780633119255c146102ee5780633792eb981461030457806338bbfa501461035757806353a04b05146103ef5780635e9a31fb146103fd5780637249fbb6146104105780637ea17a1d146104265780638579c10e146104395780638a1fde4b146104585780638aa19ef71461047257806391a1f16a14610488578063a3b9b8d11461049b578063aefbbf2a146104a3578063b5c14adb146104b6578063ba2d5c88146104ce578063cc783c5e146104e1578063dab7882014610500578063dbfc74cb14610522578063ef2e732114610535578063f2fde38b14610548578063f331020c14610567578063fb87eb0b1461057a578063fc0e64de14610592575b600080fd5b341561019757600080fd5b6101a26004356105a8565b005b34156101af57600080fd5b6101b76105d0565b60405161ffff909116815260200160405180910390f35b34156101d957600080fd5b6101e16105da565b60405190815260200160405180910390f35b34156101fe57600080fd5b6101e16105e0565b341561021157600080fd5b6101e16105e6565b341561022457600080fd5b61022c6105ec565b604051600160a060020a03909116815260200160405180910390f35b341561025357600080fd5b6101e1610603565b341561026657600080fd5b6101a2600435610609565b341561027c57600080fd5b610284610640565b604051901515815260200160405180910390f35b34156102a357600080fd5b6101a2600480359060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065095505050505050565b34156102f957600080fd5b6101a2600435610682565b341561030f57600080fd5b61031a6004356106b9565b604051600160a060020a0390951685529215156020850152604080850192909252606084015260ff909116608083015260a0909101905180910390f35b341561036257600080fd5b6101a2600480359060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405281815292919060208401838380828437509496506106f795505050505050565b6101a260ff6004351661124f565b341561040857600080fd5b6101e1611488565b341561041b57600080fd5b6101a260043561148e565b341561043157600080fd5b6101e1611652565b341561044457600080fd5b6101a2600160a060020a0360043516611658565b341561046357600080fd5b6101a261ffff600435166116b1565b341561047d57600080fd5b6101a2600435611700565b341561049357600080fd5b6101e1611734565b6101a26117b2565b34156104ae57600080fd5b61022c6117cf565b34156104c157600080fd5b6101a260043515156117de565b34156104d957600080fd5b6101e161181d565b34156104ec57600080fd5b6101a2600160a060020a0360043516611823565b341561050b57600080fd5b6101a2600160a060020a03600435166024356118de565b341561052d57600080fd5b6101e1611970565b341561054057600080fd5b6101e1611976565b341561055357600080fd5b6101a2600160a060020a036004351661197c565b341561057257600080fd5b6102846119da565b341561058557600080fd5b6101a260043515156119e9565b341561059d57600080fd5b6101a2600435611a2a565b60115433600160a060020a0390811664010000000090920416146105cb57600080fd5b600c55565b60115461ffff1681565b60095481565b60085481565b600b5481565b6011546401000000009004600160a060020a031681565b600a5481565b60115433600160a060020a039081166401000000009092041614801561063057506103e881115b151561063b57600080fd5b600d55565b6011546301000000900460ff1681565b61067e828260006040518059106106645750595b818152601f19601f830116810160200160405290506106f7565b5050565b60115433600160a060020a03908116640100000000909204161480156106a957506103e881115b15156106b457600080fd5b600e55565b6007602052600090815260409020805460018201546002830154600390930154600160a060020a0383169360ff60a060020a90940484169390911685565b6106ff614778565b60008060008061070d6147a6565b60008981526007602052604080822082918291829160a0905190810160409081528254600160a060020a038116835260ff60a060020a909104811615156020840152600184015491830191909152600283015460608301526003909201549091166080820152995061077d611a52565b600160a060020a031633600160a060020a031614801561079f57508960200151155b80156107b6575060008a51600160a060020a031614155b80156107c85750896060015160085410155b15156107d357600080fd5b6107de8d8d8d611bc9565b60ff16156108df576011546301000000900460ff16156108ad5760008d8152600760205260409020805474ff0000000000000000000000000000000000000000191660a060020a1790556008546108399060608c0151611cf3565b6008558951600160a060020a03166108fc8b606001519081150290604051600060405180830381858888f19350505050151561087457600080fd5b8c7fdda15e30b719d5c232faad22f4c2c1e8994336c026868ed0d3bc4aac71977abb60608c015160405190815260200160405180910390a25b8c7f2576aa524eff2f518901d6458ad267a59debacb7bf8700998dba20313f17dce660405160405180910390a2611240565b60086040518059106108ee5750595b90808252806020026020018201604052509450600092505b896080015160ff168360ff161015610fb35760018901985060408c8a6040518083805190602001908083835b602083106109515780518252601f199092019160209182019101610932565b6001836020036101000a0380198251168184511617909252505050919091019283525050602001905060405190819003902081151561098c57fe5b06975060018901985060408c8a6040518083805190602001908083835b602083106109c85780518252601f1990920191602091820191016109a9565b6001836020036101000a03801982511681845116179092525050509190910192835250506020019050604051908190039020811515610a0357fe5b06965060018901985060408c8a6040518083805190602001908083835b60208310610a3f5780518252601f199092019160209182019101610a20565b6001836020036101000a03801982511681845116179092525050509190910192835250506020019050604051908190039020811515610a7a57fe5b069550610a8688611d05565b9750610a9187611dca565b9650610a9c86611e95565b9550610aa9888888611f5f565b90930192601b60ff841611610b5c5782601b0360030260020160030260ff1660020a8860ff160285600081518110610add57fe5b906020019060200201818151019150818152505082601b0360030260010160030260ff1660020a8760ff160285600081518110610b1657fe5b90602001906020020181815101905250601b83900360090260ff90811660020a9087160285600081518110610b4757fe5b90602001906020020181815101905250610fa8565b603760ff841611610bf6578260370360030260020160030260ff1660020a8860ff160285600181518110610b8c57fe5b90602001906020020181815101915081815250508260370360030260010160030260ff1660020a8760ff160285600181518110610bc557fe5b90602001906020020181815101905250603783900360090260ff90811660020a9087160285600181518110610b4757fe5b605360ff841611610c95578260530360030260020160030260ff1660020a8860ff160285600281518110610c2657fe5b90602001906020020181815101915081815250508260530360030260010160030260ff1660020a8760ff160285600281518110610c5f57fe5b90602001906020020181815101915081815250508260530360030260030260ff1660020a8660ff160285600281518110610b4757fe5b606f60ff841611610d2f5782606f0360030260020160030260ff1660020a8860ff160285600381518110610cc557fe5b906020019060200201818151019150818152505082606f0360030260010160030260ff1660020a8760ff160285600381518110610cfe57fe5b90602001906020020181815101905250606f83900360090260ff90811660020a9087160285600381518110610b4757fe5b608b60ff841611610dc95782608b0360030260020160030260ff1660020a8860ff160285600481518110610d5f57fe5b906020019060200201818151019150818152505082608b0360030260010160030260ff1660020a8760ff160285600481518110610d9857fe5b90602001906020020181815101905250608b83900360090260ff90811660020a9087160285600481518110610b4757fe5b60a760ff841611610e63578260a70360030260020160030260ff1660020a8860ff160285600581518110610df957fe5b90602001906020020181815101915081815250508260a70360030260010160030260ff1660020a8760ff160285600581518110610e3257fe5b9060200190602002018181510190525060a783900360090260ff90811660020a9087160285600581518110610b4757fe5b60c360ff841611610efd578260c30360030260020160030260ff1660020a8860ff160285600681518110610e9357fe5b90602001906020020181815101915081815250508260c30360030260010160030260ff1660020a8760ff160285600681518110610ecc57fe5b9060200190602002018181510190525060c383900360090260ff90811660020a9087160285600681518110610b4757fe5b60df60ff841611610fa8578260df0360030260020160030260ff1660020a8860ff160285600781518110610f2d57fe5b90602001906020020181815101915081815250508260df0360030260010160030260ff1660020a8760ff160285600781518110610f6657fe5b9060200190602002018181510190525060df83900360090260ff90811660020a9087160285600781518110610f9757fe5b906020019060200201818151019052505b600190920191610906565b600b80548a019055600a54610fcc9060608c0151612490565b600a5560008d8152600760205260409020805474ff0000000000000000000000000000000000000000191660a060020a1790556008546110109060608c0151611cf3565b600855606460608b015181151561102357fe5b04915061103260095483612490565b600955601254600160a060020a031663fbe00e8e61105460608d015185611cf3565b6040518263ffffffff1660e060020a0281526004016000604051808303818588803b151561108157600080fd5b5af1151561108e57600080fd5b505050506110b28a6080015160ff168b606001518115156110ab57fe5b04856124aa565b601254909150600160a060020a031663becd0580828c5160405160e060020a63ffffffff85160281526004810192909252600160a060020a03166024820152604401600060405180830381600087803b151561110d57600080fd5b5af1151561111a57600080fd5b508e91507fc97a66505c1c68fd69c7d907e99a861eb4cf9a33460059bee6f6ec5a9e67793190508660008151811061114e57fe5b906020019060200201518760018151811061116557fe5b906020019060200201518860028151811061117c57fe5b906020019060200201518960038151811061119357fe5b906020019060200201518a6004815181106111aa57fe5b906020019060200201518b6005815181106111c157fe5b906020019060200201518c6006815181106111d857fe5b906020019060200201518d6007815181106111ef57fe5b90602001906020020151604051808981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019850505050505050505060405180910390a25b50505050505050505050505050565b60008060008360ff163481151561126257fe5b601154919004935062010000900460ff161580156112825750600e543410155b80156112905750600d548310155b801561129f575060008460ff16115b80156112af575060e08460ff1611155b80156112cd57506112be611734565b6112ca846113886124aa565b11155b15156112d857600080fd5b60105460125460ff8616610cc6029091019250600160a060020a03166366479c0861133660408051908101604052600681527f72616e646f6d00000000000000000000000000000000000000000000000000006020820152856124d5565b60405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b151561136c57600080fd5b5af1151561137957600080fd5b5050506113896000601e846126c3565b905060a06040519081016040908152600160a060020a033316825260006020808401829052428385015234606085015260ff88166080850152848252600790522081518154600160a060020a031916600160a060020a03919091161781556020820151815490151560a060020a0274ff00000000000000000000000000000000000000001990911617815560408201518160010155606082015181600201556080820151600391909101805460ff191660ff909216919091179055506008546114529034612490565b600855807fcfd1f319fe9af0531e626b618361fcb41e067cbc1858a3f6e7a2ec24182eca9f60405160405180910390a250505050565b600d5481565b611496614778565b600082815260076020526040908190209060a0905190810160409081528254600160a060020a038116835260ff60a060020a9091048116151560208401526001840154918301918252600284015460608401526003909301549092166080820152600c549092509061150a90429051611cf3565b1015801561154a575060115433600160a060020a0390811664010000000090920416148061154a57508051600160a060020a031633600160a060020a0316145b801561155857508060200151155b801561156a5750600854816060015111155b801561157a575060008160600151115b801561158f57506011546301000000900460ff165b151561159a57600080fd5b6000828152600760205260409020805474ff0000000000000000000000000000000000000000191660a060020a1790556008546115db906060830151611cf3565b6008558051600160a060020a03166108fc82606001519081150290604051600060405180830381858888f19350505050151561161657600080fd5b817fdda15e30b719d5c232faad22f4c2c1e8994336c026868ed0d3bc4aac71977abb606083015160405190815260200160405180910390a25050565b600c5481565b60125460009033600160a060020a0390811691161461167657600080fd5b50600980546000909155600160a060020a03821681156108fc0282604051600060405180830381858888f19350505050151561067e57600080fd5b60115433600160a060020a03908116640100000000909204161480156116dd575061014d8161ffff1611155b15156116e857600080fd5b6011805461ffff191661ffff92909216919091179055565b60115433600160a060020a03908116640100000000909204161461172357600080fd5b600f81905561173181612b61565b50565b6012546000906103e8906117a290600160a060020a0316630d1fce426040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561177e57600080fd5b5af1151561178b57600080fd5b505050604051805160115490915061ffff166124aa565b8115156117ab57fe5b0490505b90565b60125433600160a060020a039081169116146117cd57600080fd5b565b601254600160a060020a031681565b60115433600160a060020a03908116640100000000909204161461180157600080fd5b60118054911515620100000262ff000019909216919091179055565b600e5481565b60115433600160a060020a03908116640100000000909204161480156118525750601254600160a060020a0316155b151561185d57600080fd5b80600160a060020a0316630d1fce426040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561189a57600080fd5b5af115156118a757600080fd5b5050506040518051151590506118bc57600080fd5b60128054600160a060020a031916600160a060020a0392909216919091179055565b60115433600160a060020a03908116640100000000909204161461190157600080fd5b81600160a060020a031663a9059cbb338360405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b151561195557600080fd5b5af1151561196257600080fd5b505050604051805150505050565b600f5481565b60105481565b60115433600160a060020a03908116640100000000909204161461199f57600080fd5b60118054600160a060020a039092166401000000000277ffffffffffffffffffffffffffffffffffffffff0000000019909216919091179055565b60115462010000900460ff1681565b60115433600160a060020a039081166401000000009092041614611a0c57600080fd5b6011805491151563010000000263ff00000019909216919091179055565b60115433600160a060020a039081166401000000009092041614611a4d57600080fd5b601055565b60008054600160a060020a03161580611a7d5750600054611a7b90600160a060020a0316612cd8565b155b15611a8e57611a8c6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611acd57600080fd5b5af11515611ada57600080fd5b5050506040518051600154600160a060020a039081169116149050611b6f57600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611b3857600080fd5b5af11515611b4557600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663c281d19e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611bae57600080fd5b5af11515611bbb57600080fd5b505050604051805191505090565b60008082600081518110611bd957fe5b016020015160f860020a900460f860020a02600160f860020a0319167f4c00000000000000000000000000000000000000000000000000000000000000141580611c6b575082600181518110611c2b57fe5b016020015160f860020a900460f860020a02600160f860020a0319167f500000000000000000000000000000000000000000000000000000000000000014155b80611cb3575082600281518110611c7e57fe5b01602001517fff0000000000000000000000000000000000000000000000000000000000000060f860020a9182900482021614155b15611cc15760019150611ceb565b611cd4838686611ccf612cec565b612d94565b9050801515611ce65760029150611ceb565b600091505b509392505050565b600082821115611cff57fe5b50900390565b600060ff82161515611d1957506000611dc5565b60018260ff1610158015611d31575060078260ff1611155b15611d3e57506001611dc5565b8160ff1660081415611d5257506002611dc5565b60098260ff1610158015611d6a5750600d8260ff1611155b15611d7757506003611dc5565b600e8260ff1610158015611d8f575060168260ff1611155b15611d9c57506004611dc5565b60178260ff1610158015611db45750601f8260ff1611155b15611dc157506005611dc5565b5060065b919050565b6000808260ff1610158015611de3575060028260ff1611155b15611df057506000611dc5565b8160ff1660031415611e0457506001611dc5565b60048260ff1610158015611e1c5750600a8260ff1611155b15611e2957506002611dc5565b600b8260ff1610158015611e41575060118260ff1611155b15611e4e57506003611dc5565b60128260ff1610158015611e66575060178260ff1611155b15611e7357506004611dc5565b60188260ff1610158015611db45750601f60ff831611611dc157506005611dc5565b600060ff82161515611ea957506000611dc5565b60018260ff1610158015611ec1575060068260ff1611155b15611ece57506001611dc5565b60078260ff1610158015611ee65750600c8260ff1611155b15611ef357506002611dc5565b600d8260ff1610158015611f0b575060128260ff1611155b15611f1857506003611dc5565b60138260ff1610158015611f30575060198260ff1611155b15611f3d57506004611dc5565b601a8260ff1610158015611db45750601f60ff831611611dc157506005611dc5565b60008360ff1660061480611f7657508260ff166006145b80611f8457508160ff166006145b15611fc0578360ff166006148015611f9f57508260ff166006145b8015611fae57508160ff166006145b15611fbb57506001612489565b612485565b8360ff16600514156120b8578260ff166004148015611fe257508160ff166003145b15611fef5750605a612489565b8260ff16600314801561200557508160ff166004145b156120125750600f612489565b8260ff16600514801561202857508160ff166005145b156120355750600a612489565b60038360ff161015801561204d575060058360ff1611155b801561205d575060038260ff1610155b801561206d575060058260ff1611155b1561207a57506003612489565b8260ff166002148061208f57508260ff166005145b80156120ab57508160ff16600214806120ab57508160ff166005145b15611fbb57506002612489565b8360ff16600414156121a8578260ff1660041480156120da57508160ff166004145b156120e757506019612489565b8260ff1660031480156120fd57508160ff166005145b8061211957508260ff16600514801561211957508160ff166003145b156121265750600f612489565b60038360ff161015801561213e575060058360ff1611155b801561214e575060038260ff1610155b801561215e575060058260ff1611155b1561216b57506003612489565b8260ff166001148061218057508260ff166004145b80156120ab57508160ff16600114806120ab57508160ff1660041415611fbb57506002612489565b8360ff1660031415612295578260ff1660031480156121ca57508160ff166003145b156121d757506032612489565b8260ff1660041480156121ed57508160ff166005145b8061220957508260ff16600514801561220957508160ff166004145b156122165750600f612489565b60038360ff161015801561222e575060058360ff1611155b801561223e575060038260ff1610155b801561224e575060058260ff1611155b1561225b57506003612489565b60ff8316158061226e57508260ff166003145b8015612288575060ff8216158061228857508160ff166003145b15611fbb57506003612489565b8360ff166002141561232b578260ff1660011480156122b5575060ff8216155b156122c35750611388612489565b8260ff1660021480156122d957508160ff166002145b156122e6575060fa612489565b60008360ff16101580156122fe575060028360ff1611155b801561230e575060008260ff1610155b801561231e575060028260ff1611155b1561207a57506046612489565b8360ff16600114156123dc578260ff16600114801561234d57508160ff166001145b1561235a575060fa612489565b60008360ff1610158015612372575060028360ff1611155b8015612382575060008260ff1610155b8015612392575060028260ff1611155b1561239f57506046612489565b8260ff16600114806123b457508260ff166004145b801561228857508160ff166001148061228857508160ff1660041415611fbb57506003612489565b60ff841615156124855760ff83161580156123f8575060ff8216155b1561240657506106f1612489565b60008360ff161015801561241e575060028360ff1611155b801561242e575060008260ff1610155b801561243e575060028260ff1611155b1561244b57506046612489565b60ff8316158061245e57508260ff166003145b8015612478575060ff8216158061247857508160ff166003145b1561248557506003612489565b5060005b9392505050565b60008282018381101561249f57fe5b8091505b5092915050565b6000808315156124bd57600091506124a3565b508282028284828115156124cd57fe5b041461249f57fe5b60008054600160a060020a0316158061250057506000546124fe90600160a060020a0316612cd8565b155b156125115761250f6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561255057600080fd5b5af1151561255d57600080fd5b5050506040518051600154600160a060020a0390811691161490506125f257600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156125bb57600080fd5b5af115156125c857600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a0316632ef3accc84846040518363ffffffff1660e060020a0281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561265a578082015183820152602001612642565b50505050905090810190601f1680156126875780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b15156126a657600080fd5b5af115156126b357600080fd5b5050506040518051949350505050565b60006126cd6147a6565b6126d56147a6565b6126dd6147a6565b60006126e76147a6565b6126ef6147a6565b6126f76147b8565b60006127016147a6565b60008c118015612712575060208c11155b151561271d57600080fd5b600a8d029c5060016040518059106127325750595b818152601f19601f8301168101602001604052905098508b60f860020a028960008151811061275d57fe5b906020010190600160f860020a031916908160001a90535060206040518059106127845750595b818152601f19601f83011681016020016040529050975060206040518059106127aa5750595b818152601f19601f8301168101602001604052905096506127c96132ee565b95506020885242411860014303401860208901526020875285602088015260206040518059106127f65750595b818152601f19601f8301168101602001604052905094508c602086015260086040518059106128225750595b818152601f19601f830116810160200160405290509350612849856018600887600061344a565b506080604051908101604052808981526020018a81526020018881526020018681525092506128ac60408051908101604052600681527f72616e646f6d00000000000000000000000000000000000000000000000000006020820152848d61349f565b915060086040518059106128bd5750595b8181526020601f909201601f191681018201604052915084015160f860020a810460278301537e01000000000000000000000000000000000000000000000000000000000000810460268301537d0100000000000000000000000000000000000000000000000000000000008104602583015360e060020a810460248301537b01000000000000000000000000000000000000000000000000000000810460238301537a010000000000000000000000000000000000000000000000000000810460228301537901000000000000000000000000000000000000000000000000008104602183015378010000000000000000000000000000000000000000000000008104602083015350612b5182826020860151600287516040518082805190602001908083835b60208310612a045780518252601f1990920191602091820191016129e5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af11515612a4257600080fd5b50506040518051905060408801516040518085805190602001908083835b60208310612a7f5780518252601f199092019160209182019101612a60565b6001836020036101000a038019825116818451161790925250505091909101905084805190602001908083835b60208310612acb5780518252601f199092019160209182019101612aac565b6001836020036101000a038019825116818451161790925250505091909101848152602001905082805190602001908083835b60208310612b1d5780518252601f199092019160209182019101612afe565b6001836020036101000a03801982511681845116179092525050509190910195506040945050505050518091039020613693565b509b9a5050505050505050505050565b600054600160a060020a03161580612b8b5750600054612b8990600160a060020a0316612cd8565b155b15612b9c57612b9a6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612bdb57600080fd5b5af11515612be857600080fd5b5050506040518051600154600160a060020a039081169116149050612c7d57600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612c4657600080fd5b5af11515612c5357600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663ca6ad1e48260405160e060020a63ffffffff84160281526004810191909152602401600060405180830381600087803b1515612cc557600080fd5b5af11515612cd257600080fd5b50505050565b3b90565b6000612ce66136a5565b92915050565b612cf46147a6565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612d8a5780601f10612d5f57610100808354040283529160200191612d8a565b820191906000526020600020905b815481529060010190602001808311612d6d57829003601f168201915b5050505050905090565b600080612d9f6147a6565b612da76147a6565b612daf6147a6565b612db76147a6565b600080612dc26147a6565b8c604581518110612dcf57fe5b016020015160f860020a9081900481020460660197506020604051805910612df45750595b818152601f19601f830116810160200160405290509650612e1a8d8960208a600061344a565b5060028a8d6040518083805190602001908083835b60208310612e4e5780518252601f199092019160209182019101612e2f565b6001836020036101000a038019825116818451161790925250505091909101928352505060209081019150604051808303816000865af11515612e9057600080fd5b505060405180519050604051908152602001604051908190039020876040518082805190602001908083835b60208310612edb5780518252601f199092019160209182019101612ebc565b6001836020036101000a038019825116818451161790925250505091909101925060409150505190819003902014612f1657600098506132de565b8c604a890181518110612f2557fe5b016020015160f860020a900460f860020a0260f860020a9004600201604051805910612f4e5750595b818152601f19601f830116810160200160405290509550612f778d89604901885189600061344a565b506130226002876040518082805190602001908083835b60208310612fad5780518252601f199092019160209182019101612f8e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af11515612feb57600080fd5b5050604051805190508c8f60288c018151811061300457fe5b016020015160f860020a900460f860020a0260f860020a90046139c9565b151561303157600098506132de565b60296040518059106130405750595b818152601f19601f8301168101602001604052905094506130698d89602001602988600061344a565b50604080518059106130785750595b818152601f19601f8301168101602001604052905093508551886020016029010160410192506130b08d60408503604087600061344a565b506002846040518082805190602001908083835b602083106130e35780518252601f1990920191602091820191016130c4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af1151561312157600080fd5b505060405180519050915084826040518083805190602001908083835b6020831061315d5780518252601f19909201916020918201910161313e565b6001836020036101000a0380198251168184511617909252505050919091019283525050602001905060405190819003902060008d81526003602052604090205414156131b85760008c8152600360205260408120556131c1565b600098506132de565b60496040518059106131d05750595b818152601f19601f8301168101602001604052905090506131f68d89604984600061344a565b5061327a6002826040518082805190602001908083835b6020831061322c5780518252601f19909201916020918201910161320d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af1151561326a57600080fd5b5050604051805190508786613a4f565b151561328957600098506132de565b60008281526004602052604090205460ff1615156132c9576132ab8d84613c68565b6000838152600460205260409020805460ff19169115159190911790555b60008281526004602052604090205460ff1698505b5050505050505050949350505050565b60008054600160a060020a03161580613319575060005461331790600160a060020a0316612cd8565b155b1561332a576133286000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561336957600080fd5b5af1151561337657600080fd5b5050506040518051600154600160a060020a03908116911614905061340b57600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156133d457600080fd5b5af115156133e157600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663abaa5f3e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611bae57600080fd5b6134526147a6565b838201600080828651101561346657600080fd5b505060208087019084015b86886020010182101561349257818901518682015260209182019101613471565b5093979650505050505050565b60006134a96147a6565b600054600160a060020a031615806134d357506000546134d190600160a060020a0316612cd8565b155b156134e4576134e26000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561352357600080fd5b5af1151561353057600080fd5b5050506040518051600154600160a060020a0390811691161490506135c557600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561358e57600080fd5b5af1151561359b57600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b60046040518059106135d45750595b90808252806020026020018201604052801561360a57816020015b6135f76147a6565b8152602001906001900390816135ef5790505b50905083518160008151811061361c57fe5b6020908102909101015283600160200201518160018151811061363b57fe5b602090810291909101015260408401518160028151811061365857fe5b602090810291909101015260608401518160038151811061367557fe5b6020908102909101015261368a85828561404a565b95945050505050565b60009182526003602052604090912055565b6000806136c5731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed612cd8565b11156137355760008054600160a060020a031916731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed17905561372d60408051908101604052600b81527f6574685f6d61696e6e657400000000000000000000000000000000000000000060208201526143ae565b5060016117af565b600061375473c03a2615d5efaf5f49f60b7bb6583eaec212fdf1612cd8565b11156137bc5760008054600160a060020a03191673c03a2615d5efaf5f49f60b7bb6583eaec212fdf117905561372d60408051908101604052600c81527f6574685f726f707374656e33000000000000000000000000000000000000000060208201526143ae565b60006137db73b7a07bcf2ba2f2703b24c0691b5278999c59ac7e612cd8565b11156138435760008054600160a060020a03191673b7a07bcf2ba2f2703b24c0691b5278999c59ac7e17905561372d60408051908101604052600981527f6574685f6b6f76616e000000000000000000000000000000000000000000000060208201526143ae565b600061386273146500cfd35b22e4a392fe0adc06de1a1368ed48612cd8565b11156138ca5760008054600160a060020a03191673146500cfd35b22e4a392fe0adc06de1a1368ed4817905561372d60408051908101604052600b81527f6574685f72696e6b65627900000000000000000000000000000000000000000060208201526143ae565b60006138e9736f485c8bf6fc43ea212e93bbf8ce046c7f1cb475612cd8565b111561391d575060008054600160a060020a031916736f485c8bf6fc43ea212e93bbf8ce046c7f1cb47517905560016117af565b600061393c7320e12a1f859b3feae5fb2a0a32c18f5a65555bbf612cd8565b1115613970575060008054600160a060020a0319167320e12a1f859b3feae5fb2a0a32c18f5a65555bbf17905560016117af565b600061398f7351efaf4c8b3c9afbd5ab9f4bbc82784ab6ef8faa612cd8565b11156139c3575060008054600160a060020a0319167351efaf4c8b3c9afbd5ab9f4bbc82784ab6ef8faa17905560016117af565b50600090565b6000600181838551146139db57600080fd5b5060005b83811015613a42578481815181106139f357fe5b016020015160f860020a900460f860020a02600160f860020a0319168682602081101515613a1d57fe5b1a60f860020a02600160f860020a031916141515613a3a57600091505b6001016139df565b8192505b50509392505050565b6000806000806000613a5f6147a6565b6000613a696147a6565b6020604051805910613a785750595b8181526020601f909201601f19168101820160405293508a600381518110613a9c57fe5b016020015160f860020a900460f860020a0260f860020a9004036004019150613aca8a83602086600061344a565b92506020604051805910613adb5750595b818152601f19601f830116810160200160405290509050602282019150613b338a60208c6001860381518110613b0d57fe5b016020015160f860020a900460f860020a0260f860020a9004038401602084600061344a565b90506020830151945060208101519350613b508b601b87876143c1565b9097509550600160a060020a038616896040518082805190602001908083835b60208310613b8f5780518252601f199092019160209182019101613b70565b6001836020036101000a0380198251168184511617909252505050919091019250604091505051908190039020600160a060020a03161415613bd45760019750613c5a565b613be18b601c87876143c1565b9097509550600160a060020a038616896040518082805190602001908083835b60208310613c205780518252601f199092019160209182019101613c01565b6001836020036101000a0380198251168184511617909252505050919091019250604091505051908190039020600160a060020a03161497505b505050505050509392505050565b600080613c736147a6565b613c7b6147a6565b613c836147a6565b613c8b6147a6565b613c936147a6565b613c9b6147a6565b613ca36147a6565b8a8a60010181518110613cb257fe5b016020015160f860020a900460f860020a0260f860020a9004600201604051805910613cdb5750595b818152601f19601f830116810160200160405290509650613d018b8b89518a600061344a565b5060408051805910613d105750595b818152601f19601f830116810160200160405290509550613d378b6004604089600061344a565b506062604051805910613d475750595b818152601f19601f83011681016020016040529050945060f860020a85600081518110613d7057fe5b906020010190600160f860020a031916908160001a905350613d9a8b60418c03604188600161344a565b506040805190810160405280602081526020017ffd94fa71bc0ba10d39d464d0d8f465efeef0a2764e3887fcc9df41ded20f505c8152509350613de3846000602088604261344a565b50613e676002866040518082805190602001908083835b60208310613e195780518252601f199092019160209182019101613dfa565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af11515613e5757600080fd5b5050604051805190508888613a4f565b9750871515613e79576000985061403c565b606060405190810160405280604081526020017f7fb956469c5c9b89840d55b43537e66a98dd4811ea0a27224272c2e5622911e881526020017f537a2f8e86a46baec82864e98dd01e9ccc2f8bc5dfc9cbe5a91a290498dd96e481525092506042604051805910613ee75750595b818152601f19601f8301168101602001604052905091507ffe0000000000000000000000000000000000000000000000000000000000000082600081518110613f2c57fe5b906020010190600160f860020a031916908160001a905350613f548b6003604185600161344a565b508a604581518110613f6257fe5b016020015160f860020a900460f860020a0260f860020a9004600201604051805910613f8b5750595b818152601f19601f830116810160200160405290509050613fb28b6044835184600061344a565b506140366002836040518082805190602001908083835b60208310613fe85780518252601f199092019160209182019101613fc9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506020604051808303816000865af1151561402657600080fd5b5050604051805190508285613a4f565b97508798505b505050505050505092915050565b6000806140556147a6565b600054600160a060020a0316158061407f575060005461407d90600160a060020a0316612cd8565b155b156140905761408e6000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156140cf57600080fd5b5af115156140dc57600080fd5b5050506040518051600154600160a060020a03908116911614905061417157600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561413a57600080fd5b5af1151561414757600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a0316632ef3accc87866040518363ffffffff1660e060020a0281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b838110156141d95780820151838201526020016141c1565b50505050905090810190601f1680156142065780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b151561422557600080fd5b5af1151561423257600080fd5b5050506040518051925050670de0b6b3a76400003a85020182111561425a5760009250613a46565b61426385614401565b600154909150600160a060020a031663c55c1cb68360008985896040518663ffffffff1660e060020a028152600401808581526020018060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156142dc5780820151838201526020016142c4565b50505050905090810190601f1680156143095780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561433f578082015183820152602001614327565b50505050905090810190601f16801561436c5780820380516001836020036101000a031916815260200191505b5096505050505050506020604051808303818588803b151561438d57600080fd5b5af1151561439a57600080fd5b505050506040518051979650505050505050565b600281805161067e9291602001906147e5565b60008060008060405188815287602082015286604082015285606082015260208160808360006001610bb8f1925080519299929850919650505050505050565b6144096147a6565b6000806144146147a6565b60008060006144216147a6565b60008060008b519950600098508960405180591061443c5750595b90808252806020026020018201604052801561447257816020015b61445f6147a6565b8152602001906001900390816144575790505b509750600096505b898710156144ff578b878151811061448e57fe5b906020019060200201518888815181106144a457fe5b60209081029091010152601760018989815181106144be57fe5b9060200190602002015151038115156144d357fe5b048888815181106144e057fe5b906020019060200201515101989098016003019760019096019561447a565b600198909801976000955060808a0194508860405180591061451e5750595b818152601f19601f8301168101602001604052905093505b6001869011156145885760f860020a8502866001811061455257fe5b1a60f860020a0284878151811061456557fe5b906020010190600160f860020a031916908160001a905350600190950194614536565b600096505b89871015614768577f5f000000000000000000000000000000000000000000000000000000000000008487815181106145c257fe5b906020010190600160f860020a031916908160001a905350600190950194600092505b8787815181106145f157fe5b9060200190602002015151831015614714576017830615156146ad5760188389898151811061461c57fe5b906020019060200201515103101561464c578288888151811061463b57fe5b90602001906020020151510361464f565b60175b60400191508590505b808603600111156146ad5760f860020a82028187036001811061467757fe5b1a60f860020a0284878151811061468a57fe5b906020010190600160f860020a031916908160001a905350600190950194614658565b8787815181106146b957fe5b9060200190602002015183815181106146ce57fe5b016020015160f860020a900460f860020a028487815181106146ec57fe5b906020010190600160f860020a031916908160001a90535060019586019592909201916145e5565b7fff0000000000000000000000000000000000000000000000000000000000000084878151811061474157fe5b906020010190600160f860020a031916908160001a9053506001968701969095019461458d565b50919a9950505050505050505050565b60a0604051908101604090815260008083526020830181905290820181905260608201819052608082015290565b60206040519081016040526000815290565b60806040519081016040526004815b6147cf6147a6565b8152602001906001900390816147c75790505090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061482657805160ff1916838001178555614853565b82800160010185558215614853579182015b82811115614853578251825591602001919060010190614838565b5061485f929150614863565b5090565b6117af91905b8082111561485f5760008155600101614869565b600054600160a060020a031615806148a757506000546148a590600160a060020a0316612cd8565b155b156148b8576148b66000612cdc565b505b600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156148f757600080fd5b5af1151561490457600080fd5b5050506040518051600154600160a060020a03908116911614905061499957600054600160a060020a03166338cc48316040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561496257600080fd5b5af1151561496f57600080fd5b505050604051805160018054600160a060020a031916600160a060020a0392909216919091179055505b600154600160a060020a031663688dcfd78260405160e060020a63ffffffff84160281527fff000000000000000000000000000000000000000000000000000000000000009091166004820152602401600060405180830381600087803b1515612cc557600080fd00a165627a7a723058202d48f2cf6e8bfcc89fb1b8028c0e9f3ac99194db8d859ddd6bcf058cdfd9d4620029
Swarm Source
bzzr://2d48f2cf6e8bfcc89fb1b8028c0e9f3ac99194db8d859ddd6bcf058cdfd9d462
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $3,683.51 | 0.04 | $147.34 |
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.