News – Kibo contract code is now open access.
Kibo is an international lotto. Their website is at https://kiboplatform.net/en/landing.html. Here is their whitepaper.
There may be a bug bounty – (URGENT) Smart Contract Due Dilligence.
See warnings at Kibo Lotto ICO Shenanigans, After much pressure, Kibo finally release their contract code, Ethereum Community Points Out Kibo Project Flaws and Users Accuse Blockchain-Based Lottery KIBO of Scam.
I don’t like gambling platforms, but following is the smart contract code from https://github.com/alfredwoooden/kibo_central:
k_eth_main.sol
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
// main proxy contract contract K_Eth_v5 { // constants struct K_Eth_Constants { uint price_4_big; // price for 1 kibit uint kibits_4_ether; // kibits amount for 1 ether uint price_4_small; // price for partnership uint money_have; // money collected on crowdsale uint sale_period; // period when kibits and partner tokens are avaliable for buyin uint sale_left; // time for crowdsale end uint sale_start; // timestamp of crowdsale start uint sale_end; // timestamp of crowdsale end address root_wallet; // contract creater address admin_wallet; // wallet with privileges to import users address s_wallet; // safe } // contracts list struct K_Eth_Contracts { K_Users2 users; K_Ballot ballot; address ballot_address; address users_address; } // free tickets and dividends for partners and players struct Temp_User { address wallet; uint psum; // from that sum dividends were already payed; uint[12] free_1; // free tickets for 6/49 uint[12] free_2; // free tickets for joker uint game_1; // drawing to start count free tickets spending uint game_2; // drawing to start count free tickets spending } struct K_Eth_Game { address game_address; // game contracts address uint active; // flag to turn game on(1)/off(0) uint price; // ticket price uint drawing; mapping (uint => uint) group_game_price; // groupgame part price } mapping(uint => K_Eth_Game) games; // game contracts list uint games_length; // length of game contracts list mapping // structure for through users iterations mapping(address => uint) temp_user2index; mapping(uint => Temp_User) index2temp_user; uint temp_user_length = 0; uint public profit; // contract profit on selling tickets uint pay_dividends_length; // paying dividends iterator uint pay_dividends_timestamp; // timestamp (to spread iterations for several blocks) uint[7] ref4level; // partners you need to get referral bonuses K_Eth_Constants public constants; K_Eth_Contracts public contracts; uint public day = 1; // day of crowdsale modifier onlyVotes { if (msg.sender != contracts.ballot_address) throw; _ } // only voting contract modifier onlyOwner { if (msg.sender != constants.root_wallet) throw; _ } // only contract creator modifier onlyAdmin { if (msg.sender != constants.admin_wallet) throw; _ } // only privileges holder modifier onlyLotto { if (msg.sender != games[1].game_address && msg.sender != games[2].game_address) throw; _ } // only game modifier SaleIsOn { if (block.timestamp < constants.sale_start || constants.sale_end != 0) throw; _ } // only during crowdsale modifier SaleIsNotEnded { if (constants.sale_end != 0) throw; _ } // only during crowdsale function K_Eth_v5 (address _admin, address _s) { constants.price_4_big = 20000000000000000; // 50 for 1 ether constants.kibits_4_ether = 50; constants.price_4_small = 10 ether; // 1 ether constants.money_have = 0; constants.sale_start = block.timestamp + 369600; constants.sale_end = 0; constants.sale_period = 40 days; constants.sale_left = 40 days; constants.root_wallet = msg.sender; constants.admin_wallet = _admin; constants.s_wallet = _s; profit = 0; pay_dividends_length = 0; pay_dividends_timestamp = block.timestamp; index2temp_user[temp_user_length].wallet = msg.sender; index2temp_user[temp_user_length].psum = 0; temp_user2index[msg.sender] = temp_user_length; temp_user_length += 1; ref4level = [2,3,3,4,5,6,7]; // partners you need to get referral bonuses } // changes kibits price, and crowdsale timestamps during crowdsale function setSalePeriod() private { if (constants.sale_end == 0 && block.timestamp > constants.sale_start) { if (block.timestamp > constants.sale_start + constants.sale_period) { endSalePeriod(); } else { constants.sale_left = constants.sale_period - (block.timestamp - constants.sale_start); uint cur_day; cur_day = (constants.sale_period - constants.sale_left) / 1 days + 1; if (day < cur_day) { day = cur_day; // price for kibit changes during the crowdsale if (day >= 30 && constants.price_4_big < 1 ether / 25) { constants.price_4_big = 1 ether / 25; constants.kibits_4_ether = 25; } if (day >= 20 && constants.price_4_big < 1 ether / 30) { constants.price_4_big = 1 ether / 30; constants.kibits_4_ether = 30; } if (day >= 10 && constants.price_4_big < 1 ether / 35) { constants.price_4_big = 1 ether / 35; constants.kibits_4_ether = 35; } if (day >= 5 && constants.price_4_big < 1 ether / 40) { constants.price_4_big = 1 ether / 40; constants.kibits_4_ether = 40; } } } } } // when crowdsale ends function endSalePeriod() private { constants.sale_end = block.timestamp; } // register partner/player // _type: 0 - partner, 1 - player // _token: 1 - partner token, 2 - kibits function register(uint _type, string _username, string _parentname, uint _token) { // checking username existance if (contracts.users.checkUsername(_username) == false) { uint drawing_1 = games[1].drawing > 0 ? games[1].drawing : 1; uint drawing_2 = games[2].drawing > 0 ? games[2].drawing : 1; index2temp_user[temp_user_length].wallet = msg.sender; index2temp_user[temp_user_length].psum = profit; index2temp_user[temp_user_length].free_1 = [3,3,3,3,3,3,3,3,3,3,3,3]; index2temp_user[temp_user_length].free_2 = [3,3,3,3,3,3,3,3,3,3,3,3]; index2temp_user[temp_user_length].game_1 = games[1].drawing; index2temp_user[temp_user_length].game_2 = games[2].drawing; temp_user2index[msg.sender] = temp_user_length; temp_user_length += 1; if (_type == 0) { contracts.users.registerPartner(msg.sender, _username, _parentname, 0); contracts.users.registerPlayer(msg.sender, _username, _parentname); if (_token == 1) { setSmall(); } else if (_token == 2) { setBig(); } } else if (_type == 1) { contracts.users.registerPlayer(msg.sender, _username, _parentname); } } } // referral payouts function payPartnerRefs (uint _package, uint _value, uint _change) private { uint refs = 0; // get first parent to pay referrals address recipient = contracts.users.getPartnerParents(msg.sender)[0]; // new partner or partner registered before crowdsale // different payouts for different types uint p_type = contracts.users.getPartnerType(recipient); if (contracts.users.getSmall(recipient) > 0) { // if partner was registered before crowdsale he gets referral bonuses from both kibits and partner tokens if (p_type > 0) { if (_package == 1) { refs = 3 ether; } else if (_package == 2) { refs += (_value * constants.price_4_big) / 100 * 15; } else if (_package == 3) { refs = 3 ether; refs += (_value * constants.price_4_big) / 100 * 15; } // else he gets referral bonuses only from partner tokens } else { if (_package == 1 || _package == 3) { refs = 3 ether; } } if (!recipient.send(refs)) throw; } constants.s_wallet.send((msg.value - _change) - refs); constants.money_have += (msg.value - _change) - refs; setSalePeriod(); } // calculate amount of kibits from msg.value function calculateBig(uint _value) constant returns (uint[2] ret_big) { uint change = _value % 1 ether; uint amount = ((_value - change) / 1 ether) * constants.kibits_4_ether; if (amount < 1) throw; return [amount, change]; } function setBig() SaleIsOn { uint[2] memory values; uint package = 2; // checking partner existance if (contracts.users.checkPartner(msg.sender)) { if (contracts.users.getSmall(msg.sender) == 0) { // first buy includes partner token and 5000 kibits - 110 ether if (msg.value < 100 ether + getPrice4Small()) throw; values = calculateBig(msg.value - getPrice4Small()); contracts.users.setSmall(msg.sender, 1); package = 3; } else { // first kibits buy should be 100 ether if (contracts.users.getBig(msg.sender) == 0 && msg.value < 100 ether) throw; values = calculateBig(msg.value); } uint value = values[0]; uint change = values[1]; uint tokens_left = contracts.users.getBigLimit(); // if amount of kibits in contract is enough if (tokens_left < value || tokens_left - value > tokens_left) throw; if (contracts.users.getBig(msg.sender) + value < contracts.users.getBig(msg.sender)) throw; contracts.users.setBig(msg.sender, value); if (change > 0) { msg.sender.send(change); } // payout referrals payPartnerRefs(package, value, change); } else { throw; } setSalePeriod(); } function calculateSmall(uint _value) constant returns (uint ret_change) { if (_value < constants.price_4_small) throw; return _value - 1 * constants.price_4_small; } function setSmall() SaleIsNotEnded { // checking partner existance if (contracts.users.checkPartner(msg.sender)) { if (contracts.users.getSmallLimit() <= 5000) throw; uint change = calculateSmall(msg.value); if (contracts.users.getSmallLimit() < 1) throw; if (contracts.users.getSmall(msg.sender) > 0 || contracts.users.getBig(msg.sender) > 0) throw; contracts.users.setSmall(msg.sender, 1); if (change > 0) { msg.sender.send(change); } // payout referrals payPartnerRefs(1, 1, change); } else { throw; } setSalePeriod(); } function calculateTicket (uint _value, uint _drawing, uint _id) internal constant returns (uint[2] ret_ticket) { uint amount = 1; if (amount < 1) throw; if (games[_id].price * _drawing > _value) throw; uint change = _value - amount * games[_id].price * _drawing; return [amount, change]; } // amount of available free tickets // _id - id of game (6/49 or joker) function getFreeTickets(uint _id) constant returns (uint ret_value) { // drawings passed since partner registration uint passed = 0; if (_id == 1) { if (index2temp_user[temp_user2index[msg.sender]].game_1 == 0) return 0; // calculating amount from drawing data return index2temp_user[temp_user2index[msg.sender]].free_1[games[1].drawing - index2temp_user[temp_user2index[msg.sender]].game_1]; } else if (_id == 2) { if (index2temp_user[temp_user2index[msg.sender]].game_2 == 0) return 0; // calculating amount from drawing data return index2temp_user[temp_user2index[msg.sender]].free_2[games[2].drawing - index2temp_user[temp_user2index[msg.sender]].game_2]; } } // "buying" free tickets function buyFreeTicket(uint _id, uint[6] _user_numbers, string _user_random) { if (_id == 1) { index2temp_user[temp_user2index[msg.sender]].free_1[games[1].drawing - index2temp_user[temp_user2index[msg.sender]].game_1] -= 1; // calling contract method. // Using "call" method cuz we need the opportunity // to include new games without main proxy contract recreation. games[1].game_address.call(bytes4(sha3("buyFreeTicket(address,uint256[6],string)")), msg.sender, _user_numbers, _user_random); } if (_id == 2) { index2temp_user[temp_user2index[msg.sender]].free_2[games[2].drawing - index2temp_user[temp_user2index[msg.sender]].game_2] -= 1; games[2].game_address.call(bytes4(sha3("buyFreeTicket(address,uint256[6],string)")), msg.sender, _user_numbers, _user_random); } } // buying ticket // _user_random - random string for win numbers generation // _user_numbers - 6 numbers user choosed // _drawing - amount of games, user wants to play // _id - game id // _double - doubling bet for joker function buyTicket(string _user_random, uint[6] _user_numbers, uint _drawing, uint _id, uint _double) { // if game is available if (games[_id].active == 0) throw; // if sender is partner or player if (contracts.users.checkPlayer(msg.sender) || contracts.users.checkPartner(msg.sender)) { uint sum = 0; // if you have free available tickets, you can not buy tickets if (getFreeTickets(_id) > 0) { buyFreeTicket(_id, _user_numbers, _user_random); return; } uint[2] memory calculated = calculateTicket(msg.value, _drawing, _id); profit += msg.value - calculated[1]; sum = (msg.value - calculated[1]) - pay4Ticket(calculated[1]) - payDividends(); if (_id == 1) { games[1].game_address.call(bytes4(sha3("buyTicket(address,uint256[6],uint256,string)")), msg.sender, _user_numbers, _drawing, _user_random); games[1].game_address.call(bytes4(sha3("transferSum(uint256)")), sum); games[1].game_address.call.gas(200000).value(sum)(); } if (_id == 2) { games[2].game_address.call(bytes4(sha3("buyTicket(address,uint256,uint256,uint256,string)")), msg.sender, _user_numbers, _drawing, _double, _user_random); games[2].game_address.call(bytes4(sha3("transferSum(uint256)")), sum); games[2].game_address.call.gas(200000).value(sum)(); } // transfer sum payed for ticket to game contract; msg.sender.send(calculated[1]); } else { throw; } } function calculateGroupTicket(uint _value, uint _id, uint _amount, uint _length) internal constant returns (uint[2] ret_ticket) { if (_amount < 1) throw; if (games[_id].group_game_price[_length] * _amount > _value) throw; uint change = _value - _amount * games[_id].group_game_price[_length] * _amount; return [_amount, change]; } // buying group ticket, mostly same to usual ticket function buyGroupTicket(uint _id, uint _length, uint _amount) { if (games[_id].active == 0) throw; if (contracts.users.checkPlayer(msg.sender) || contracts.users.checkPartner(msg.sender)) { uint sum = 0; uint[2] memory calculated = calculateGroupTicket(msg.value, _id, _amount, _length); profit += msg.value - calculated[1]; sum = (msg.value - calculated[1]) - pay4Ticket(calculated[1]) - payDividends(); games[_id].game_address.send(sum); games[_id].game_address.call(bytes4(sha3("buyGroupTicket(address,uint256,uint256)")), msg.sender, _length, _amount); games[_id].game_address.call(bytes4(sha3("transferSum(uint256)")), sum); msg.sender.send(calculated[1]); } else { throw; } } function pay4Ticket(uint _change) private returns (uint _ret_refs) { address parent; address[8] memory parents; uint parents_level_need; uint partner_type; uint level; uint refs; // get senders parent-parent if (!contracts.users.checkPartner(msg.sender)) { for (uint i = 0; i < 7; i++) { // get first partner from player parents structure and its level if (contracts.users.checkPartner(contracts.users.getPlayerParents(msg.sender)[i])) { parent = contracts.users.getPlayerParents(msg.sender)[i]; partner_type = contracts.users.getPartnerType(parent); level = i + 1; break; } } // if player is partner, he is his own parent } else { parent = msg.sender; partner_type = contracts.users.getPartnerType(parent); level = 1; } // create referral recipients chain parents[0] = parent; // 5 level structure for new partners if (partner_type == 1) {parents_level_need = 5;} // 7 level structure for partners registered before crowdsale else {parents_level_need = 7;} // do payouts if partners amount enough if (level <= parents_level_need) { for (i = 1; i < 7; i++) { parents[i] = contracts.users.getPartnerParents(parents[0])[i]; } for (i = 0; i < 7; i++) { if (contracts.users.getPartnersPerLevel(i + 1, parents[i]) >= ref4level[i]) { if (i == 0) { refs += (msg.value - _change) / 10; if (!parents[i].send((msg.value -_change) / 10)) throw; } else { refs += (msg.value - _change) / 100; if (!parents[i].send((msg.value - _change) / 100)) throw; } } } } return refs; } // payout dividends for every partner during several blocks function payDividends () private returns (uint ret_value) { uint total = 0; uint part = 0; // all dividends should be payed during through day if (block.timestamp - 1 days > pay_dividends_timestamp) { pay_dividends_timestamp = block.timestamp; pay_dividends_length = 0; } // 5 partners for iteration uint max = 5; if (temp_user_length - pay_dividends_length < 5) max = temp_user_length - pay_dividends_length; uint start = pay_dividends_length; uint end = pay_dividends_length + max; if (max > 0) { for (uint i = start; i < end; i++) { // partner gets his part for every partners kibit part = (((profit - index2temp_user[i].psum) / 100 * 14) / 350000000) * contracts.users.getBig(index2temp_user[i].wallet); // minimum amout to pay. // to avoid chance, when transaction fee will be bigger then payout if (part >= 36101083032490980) { if (!index2temp_user[i].wallet.send(part)) throw; index2temp_user[i].psum += profit; total += part; } } pay_dividends_length += max; } return total; } // import user by admin function importUser(address _address, string _username, string _parentname, uint _big, uint _small) onlyAdmin { index2temp_user[temp_user_length].wallet = _address; index2temp_user[temp_user_length].psum = profit; temp_user2index[_address] = temp_user_length; temp_user_length += 1; index2temp_user[temp_user_length - 1].free_1 = [3,3,3,3,3,3,3,3,3,3,3,3]; index2temp_user[temp_user_length - 1].free_2 = [3,3,3,3,3,3,3,3,3,3,3,3]; index2temp_user[temp_user_length - 1].game_1 = games[1].drawing; index2temp_user[temp_user_length - 1].game_2 = games[2].drawing; contracts.users.registerPartner (_address, _username, _parentname, 1); contracts.users.registerPlayer (_address, _username, _parentname); contracts.users.setBig(_address, _big); contracts.users.setSmall(_address, _small); } // call changing wallet function function changeWallet(address _donor, address _recipient) onlyAdmin { index2temp_user[temp_user_length] = index2temp_user[temp_user2index[_donor]]; index2temp_user[temp_user_length].wallet = _recipient; temp_user2index[_donor] = temp_user_length; temp_user_length += 1; contracts.users.changeWallet(_donor, _recipient); } function getPrice4Big() constant returns (uint ret_val) { return constants.price_4_big; } function getPrice4Small() constant returns (uint ret_val) { return constants.price_4_small; } // set contract addresses // for opportunity to create contracts separately function setBallotAddress(address _address) onlyOwner { contracts.ballot = K_Ballot(_address); contracts.ballot_address = _address; } function setUsersAddress(address _address) onlyOwner { contracts.users = K_Users2(_address); contracts.users_address = _address; } function setGameAddress(uint _id, address _address, uint _price) onlyOwner { games[_id].game_address = _address; games[_id].active = 1; games[_id].price = _price; games[_id].drawing = 1; games_length += 1; } // setters function setGameDrawing(uint _id, uint _drawing) onlyLotto { games[_id].drawing = _drawing; } function setGroupGamePrice(uint _id, uint _length, uint _price) { games[_id].group_game_price[_length] = _price; } function setGamePeriod(uint _id, uint _period) onlyVotes { games[_id].game_address.call(bytes4(sha3("setPeriod(uint256)")), _period); } function setGameTime(uint _id, uint _time) onlyVotes { games[_id].game_address.call(bytes4(sha3("setTime(uint256)")), _time); } function setPrice4Big(uint _value) onlyVotes { constants.price_4_big = _value; } function setPrice4Small(uint _value) onlyVotes { constants.price_4_small = _value; } function setPrice4Ticket(uint _id, uint _value) onlyVotes { games[_id].price = _value; } function changeMainContract(address _address) onlyVotes { contracts.users.setMainAddress(_address); contracts.ballot.setMainAddress(_address); for (uint i = 1; i < games_length + 1; i++) { games[i].game_address.call(bytes4(sha3("setMainAddress(address)")), _address); } } function changeVoteContract(address _address) onlyVotes { contracts.ballot = K_Ballot(_address); contracts.ballot_address = _address; } function setSmallLimit(uint _value) onlyVotes { contracts.users.setSmallLimit(_value); } function setBigLimit(uint _value) onlyVotes { contracts.users.setBigLimit(_value); } function turnGame(uint _id, uint _value) onlyVotes { games[_id].active = _value; } function getPlayerParents(address _address) constant returns (address[8] ret_parents) { return contracts.users.getPlayerParents(_address); } function getPrize (uint _id, uint _value) constant returns (uint) { if (_value == 2) return games[_id].price; if (_value == 3) return games[_id].price * 3; if (_value == 7) return games[_id].price + games[_id].price / 100 * 70; } function getSafeWallet () constant returns (address) { return constants.s_wallet; } function initGame(uint _id) onlyAdmin { games[_id].game_address.call(bytes4(sha3("startTheParty()"))); } function() {} } contract K_Ballot { function setMainAddress(address _address) { } } |
k_eth_users.sol
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
// contract - user storage (wallet, tokens, user2user structure, shareholders) contract K_Users2 { // constants struct K_Users_Constants { uint big_limit; // kibits tokens uint small_limit; // partners limit uint big_sold; // kibits sold uint small_sold; // partner tokens sold address k_address; // main proxy contract K_Eth_v5 k; } // user data struct K_Users_User { uint shareholder; // if user is shareholder uint big; // amount of kibits 2 user uint small; // if user is partner uint partner_type; // 0 - new, 1 - registered before platform start string username; // login uint[8] partner_parents; // parents-partners structure for 7 levels uint[8] partner_parents_level; // user have %q% partners at level of 7 uint[8] player_parents; // parents-players structure for 7 levels uint[8] player_parents_level; // user have %q% players at level of 7 } K_Users_Constants public constants; mapping (string => address) username2address; // to get partner wallet from username mapping (address => uint) address2id; // to get user id from user wallet mapping (uint => address) id2address; // to get user wallet from id uint id_length; // length of id-address mapping (iterations) mapping (uint => K_Users_User) users; mapping (address => uint) partner; mapping (address => uint) player; modifier mainContract { if (msg.sender != constants.k_address) throw; _ } // only main proxy contract can do this function K_Users2 (address _k) { constants.big_limit = 100000000; constants.small_limit = 25000; constants.k = K_Eth_v5(_k); constants.k_address = _k; // root user id_length = 1; address2id[msg.sender] = id_length; id2address[id_length] = msg.sender; username2address["mralfredwooden"] = msg.sender; users[id_length].shareholder += 1000; users[id_length].username = "mralfredwooden"; partner[msg.sender] += 1; player[msg.sender] += 1; // will be next user id_length += 1; } // if we change main proxy contract, the old one can rewrite this; function setMainAddress(address _k) mainContract { constants.k_address = _k; constants.k = K_Eth_v5(_k); } // link shareholder token to user function setShareholder(address _shareholder, uint _value) { // only another shareholder if (getShareholder(msg.sender) == 0) throw; if (users[address2id[msg.sender]].shareholder < _value) throw; if (users[address2id[_shareholder]].shareholder + _value < users[address2id[_shareholder]].shareholder) throw; users[address2id[msg.sender]].shareholder -= _value; users[address2id[_shareholder]].shareholder += _value; } // check if user is shareholder function getShareholder (address _address) constant returns (uint ret_value) { return users[address2id[_address]].shareholder; } // partner registration function registerPartner (address _address, string _username, string _parentname, uint _type) mainContract { uint index = 0; // there are no partners with this wallet if (partner[_address] == 0 && partner[username2address[_parentname]] > 0) { address2id[_address] = id_length; id2address[id_length] = _address; partner[_address] += 1; if (username2address[_username] == 0) { username2address[_username] = _address; } users[id_length].partner_type = _type; users[id_length].username = _username; // first parent users[id_length].partner_parents[0] = address2id[username2address[_parentname]]; users[address2id[username2address[_parentname]]].partner_parents_level[0] += 1; // other parents are parents of first one for (uint i = 0; i < 7; i++) { if (users[address2id[username2address[_parentname]]].partner_parents[i] != 0) { index += 1; users[id_length].partner_parents[index] = users[address2id[username2address[_parentname]]].partner_parents[i]; users[users[address2id[username2address[_parentname]]].partner_parents[i]].partner_parents_level[index] += 1; } } id_length += 1; } else { throw; } } function registerPlayer (address _address, string _username, string _parentname) mainContract { uint index = 0; bool count_player = false; // there are no partners with this wallet if (player[_address] == 0 && player[username2address[_parentname]] > 0) { // player could be also a partner, partner always a player if (partner[_address] == 0) { address2id[_address] = id_length; id2address[id_length] = _address; id_length += 1; } player[_address] += 1; if (username2address[_username] == 0) { username2address[_username] = _address; } users[address2id[_address]].username = _username; // if player is not a partner if (partner[_address] == 0) { users[address2id[_address]].player_parents[0] = address2id[username2address[_parentname]]; if (checkPartner(username2address[_parentname]) && !count_player) { users[address2id[username2address[_parentname]]].player_parents_level[0] += 1; count_player = true; } else { for (uint i = 0; i < 7; i++) { if (users[address2id[username2address[_parentname]]].player_parents[i] != 0) { index += 1; users[address2id[_address]].player_parents[index] = users[address2id[username2address[_parentname]]].player_parents[i]; if (checkPartner(id2address[users[address2id[username2address[_parentname]]].player_parents[i]]) && !count_player) { users[users[address2id[username2address[_parentname]]].player_parents[i]].player_parents_level[index] += 1; break; } } } } // if he is } else { // partner-player is self parent, he gets bonuses from himself; users[address2id[_address]].player_parents[0] = address2id[_address]; users[address2id[_address]].player_parents_level[0] += 1; count_player = true; } } else { throw; } } // somebody get kibits function setBig(address _address, uint _value) mainContract { constants.big_limit -= _value; constants.big_sold += _value; users[address2id[_address]].big += _value; } // somebody became a partner function setSmall(address _address, uint _value) mainContract { constants.small_limit -= _value; constants.small_sold += _value; users[address2id[_address]].small += _value; } // kibits from one person to another (for buying and selling in the future) function transferBig(address _donor, address _recipient, uint _value) mainContract { users[address2id[_donor]].big -= _value; users[address2id[_recipient]].big += _value; } // if player becomes partner (future opportunity) function setPartner(address _address) mainContract { partner[_address] += 1; } // for start period people should change automatically generated wallets for manually created by themselves function changeWallet(address _donor, address _recipient) mainContract { if (address2id[_donor] > 0) { uint id = address2id[_donor]; id2address[id] = _recipient; address2id[_recipient] = id; username2address[users[id].username] = _recipient; delete address2id[_donor]; delete partner[_donor]; partner[_recipient] += 1; } } function getSmall (address _address) constant returns (uint ret_small) { return users[address2id[_address]].small; } function getBig (address _address) constant returns (uint ret_big) { return users[address2id[_address]].big; } // if it was decided to change total amount of kibits function setBigLimit(uint _value) mainContract { constants.big_limit = _value; } // if it was decided to change total amount of partners function setSmallLimit(uint _value) mainContract { constants.small_limit = _value; } function getBigLimit() constant returns (uint ret_value) { return constants.big_limit; } function getSmallLimit() constant returns (uint ret_value) { return constants.small_limit; } function getBigSold() constant returns (uint ret_value) { return constants.big_sold; } function getSmallSold() constant returns (uint ret_value) { return constants.small_sold; } // new partner, or registere before crowdsale function getPartnerType(address _address) constant returns (uint ret_type) { return users[address2id[_address]].partner_type; } // exist or not function checkUsername(string _username) constant returns (bool ret_value) { if (username2address[_username] > 0) {return true;} else {return false;} } // total amount of related partners function getPartners() constant returns (uint count) { uint q = 0; for (uint i = 0; i < 7; i++) { q += users[address2id[msg.sender]].partner_parents_level[i]; } return q; } // total amount of related players function getPlayers() constant returns (uint count) { uint q = 0; for (uint i = 0; i < 7; i++) { q += users[address2id[msg.sender]].player_parents_level[i]; } return q; } // amount of related partners on specified level function getPartnersPerLevel(uint _level, address _address) constant returns (uint count) { return users[address2id[_address]].partner_parents_level[_level - 1]; } // amount of related players on specified level function getPlayersPerLevel(uint _level, address _address) constant returns (uint count) { return users[address2id[_address]].player_parents_level[_level - 1]; } // if partners is shareholder function checkShareholder(address _possible_shareholder) constant returns (bool ret_shareholder) { if (users[address2id[_possible_shareholder]].shareholder > 0) return true; else return false; } // to get all 7 partners-parents of specified wallet function getPartnerParents(address _address) constant returns (address[8] ret_parents) { address[8] memory tmp_arr; for(uint i = 0; i < 7; i++) { tmp_arr[i] = id2address[users[address2id[_address]].partner_parents[i]]; } return tmp_arr; } // to get all 7 players-parents of specified wallet function getPlayerParents(address _address) constant returns (address[8] ret_parents) { address[8] memory tmp_arr; for(uint i = 0; i < 7; i++) { tmp_arr[i] = id2address[users[address2id[_address]].player_parents[i]]; } return tmp_arr; } // exist or not function checkPlayer(address _address) constant returns (bool ret_player) { if (player[_address] != 0) return true; else return false; } // exist or not function checkPartner(address _address) constant returns (bool ret_player) { if (partner[_address] != 0) return true; else return false; } } |