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
// 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
// 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;
}
}