CRYPTU.IO
FARTY.logo
lottery.php
Responsive image


Digital Era


 

 

Today is the digital era! The millennium of computer technology. One of the hottest topics in this field is the new technology of crypto currencies. Since the day in which Satoshi invented the first crypto currency, the Bitcoin, several thousands of crypto currencies have been created.

 

Due to the lack of trust as a result of the 2008 global financial crisis, the leading cryptocurrency, Bitcoin, is increasingly thought of as an alternative to the prevailing financial architecture by presenting a technologically more trustworthy alternative. Because of the effect it had due to its number of users, volume, and market size, Bitcoin attracted the attention of the whole world.

 

By using blockchain technology and mining, cryptucurrencies attempts to replace the services based on trust and the mediation role offered by banks in the traditional finance system. With their characteristics such as low cost, fast transaction times, and low risks, cryptucurrencies first emerged in 2008 and since then, due to these benefits, have triggered an important change and transformation.

CryptuProEco® (Cryptu Promotion Ecosystem)


 

 

CryptuProEco® White Paper


 

 

Customer attraction has been one of the controversial issues among marketing managers in the current decade. More attraction and satisfaction mean, more success.

 

The Cryptu Promotion Manager Ecosystem (CryptuProEco®) emphasis on the customer attraction technique in which authors claim it would be the newest with innovation. There are two definitions as promoter and cluster to empower the level of the desired marketing. In this technique, sellers can create their own Services to sell their articles with the help of promoters who may promote the Providers’ articles. So for more information about the project, please read the White Paper!


Promotion Manager Contract


 

 

CryptuProEco® Contract


Cryptu Promotion Manager V1

 

Smart contract implementation of Cryptu Promotion Manager Ecosystem (CryptuProEco®).


Contract info

 

Contract name: CryptuPromotionManager

 

Contract address: 0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c

 

View CryptuPromotionManager.sol on BscScan.

 

View the Promotion Manager Ecosystem White Paper for more information.


Cryptu Promotion Manager Ecosystem Structure

 

The Promotion Manager Ecosystem, which is invented by Cruptu.io is a novel crypto currency ecosystem (CryptuProEco®), in which sellers (Providers in this context) can create their own Services to sell their goods/services with the help of Promoters who they advertise and promote the Providers's articles.

 

Each Service consists of Clusters and Promoters. Each Cluster can contain up to 15 Promoters. Promotion Manger Ecosystem structure is shown in Fig. 1.

 

Fig. 1: Promotion Manager Ecosystem Structure.

 

The Cluster structure is shown in the Fig. 2.

 

Fig. 2: Cluster Structure and its Promoters.

 

Each Promoter can have 2 sub-Promoters with direct connections as shown in the figure. When a Promoter registers in a Service without any referral code, a new Cluster is generated automatically and the Promoter becomes its owner also a referral code is generated and assigned to him/her by the Promotion Manager. The Promoter level is the lowest (4) now. If he gives his referral code to others, and they register in this Service, so they will be added as the children of the first Promoter. If two people added as sub-Promoter of the 1st Promoter, all Promoters would be leveled up, so a Promoter must invite 2 people to be his/her sub-Promoters to upgrade his/her own level. The Promoter can invite others by his/her own referral code.

 

The topmost Promoter in a full Cluster, would have level 1 (first rank) , so it would benefit of the highest Direct Commission of sales.

 

The Cluster structure is somehow like a pyramid network marketing, but it has some major differences:

 

1. Number of members is limited to 15 Promoters, and it is not unlimited like many scamming pyramid marketing networks, in which nothing earned by sub members due to huge number of network members.

 

2. Nothing paid from sub-Promoters commissions to the upper Promoters. The upper Promoters, just get their own commission from their own direct sale. This is in contrast with pyramid networks, that the top most members take benefit of the lower members' sale commission.

 

3. Recruiting sub-Promoters by top Promoters, just level them up. So as the Promoters' level grows up, their Direct Commission becomes more. This is why a Promoter needs to add sub-Promoters to himself/herself.

 

4. Unlike most pyramid networks that don't sell anything but get money from sub members, this ecosystem, don't get any money from Promoters, just Providers pay a registration fee (cash or sale percentage), so there is not anything to be paid by sub-Promoters to the tops.

 

Direct Commission is calculated based on the sale average of the Promoter per time, for example this average can be daily or any time slice in the order of seconds, This parameter is called AveragingPeriod.

 

Each Cluster in a Service, has its own Rank, which is based on sale average of its Promoters. According to this sale average, Cluster Rank can be defined. So a Cluster can be ranked up due to its sale average. As the Cluster Rank grows up, its Cluster Commission increases, so every Promoter in this Cluster can benefit of more Cluster Commission than a low rank Cluster. This is the philosophy of making Clusters.

 

Total Commission (%) = Z1 * F1 + Z2 * F2

 

F1 = (0.4593 * (PromoterSaleAverage) 2) + (0.4674 * PromoterSaleAverage) + 0.0733 and F1 <= 1

 

F2 = (ClusterLevelShare [PromoterLevel] * ClusterScore * 0.25);

 

Default Parameters:

Z1; Direct Commission Weight Factor (Ex: 0.16)

 

Z2; Cluster Commission Weight Factor (Ex: 0.24)

 

Promoter Level ClusterLevelShare
1 40%
2 30%
3 20%
4 10%

 

ClusterRank ClusterSaleAverage ClusterScore
1 0≤x<0.5 20%
2 0.5≤x<1 40%
3 1≤x<1.5 60%
4 1.5≤x<2 80%
5 2≤x 100%

 

All of the above parameters can be set by Providers during Service registration and they can be changed later.

 

Cluster Rank, is subject to degrade if a Cluster sale average drops during time. So the Promoters must try to sale more to keep their Cluster Rank up. To prevent sudden drop of the Cluster Rank, upon intermittent drop of sale, the clusterRankRelaxationPeriod parameter is defined. It is a period of time that a Cluster Rank would be kept intact, if it sales nothing or a new Promoter added to it. Default value (period) of this parameter is a week in seconds, but it can be set by the Provider to any value up to 6 months.

 

All data and history of Providers and Promoters can be viewed and changed in the CryptuProEco® dashboard.

 

The above mentioned ecosystem is developed as an EVM-Based smart contract with the limits of 100 Services that each one can handle 15000 Promoters, organized in 1000 Clusters per Service, according to the limits of available EVMs.

 

Read/View Functions

 

getServicesCount

 

 
function getServicesCount() notContract external view returns (uint16)
						

 

Returns count of registered services.

 

getServiceStatus

 

 
function getServiceStatus(uint16 serviceId) notContract external view returns(ServiceStatus memory)
						

 

Returns ServiceStatus structure of the Service using its ID; Read Promotion Manager Ecosystem White Paper for more information.

 

 
struct ServiceStatus//10 slots
    {
        bytes32 name;
        uint32 z1;
        uint32 z2;
        uint32 minDiscount;
        uint32 maxDiscount;
        bytes32 website;
        uint32 clusterRankRelaxationPeriod;
        uint32 promoterAveragingPeriod;
       //256 bits-1 slot
        bool enabled;
        uint16 id;
        uint16 clustersCount;
        uint16 promotersCount;
        address creator;
        //216 bits -1s lot
        uint256 fee;//1 slot
        address consumer;
        address currency;
        address DexRouter;
        //480 bits-3 slots
        bytes32 providerContact;
        ClusterBreak[MAX_CLUSTER_RANK] clusterShare;//480bits-3 lot
        uint32[MIN_NODE_LEVEL-1] clusterLevelShare;//128 bits-1slot
    }
						

 

Item Type Description
name bytes32 Zero padded 32 bytes Service name.
z1 uint32 Direct sale factor percentage. Must be <= 10000 (100%).
z2 uint32 Cluster sale factor percentage. Must be <= 10000 (100%).
minDiscount uint32 Minimum discount of referral codes. Must be <
maxDiscount uint32 Maximum discount of referral codes. Must be > minDiscount
website bytes32 Zero padded 32 bytes Provider's website address.
clusterRankRelaxationPerid uint32 Relaxation period of Clusters in this Service in seconds, Ex: 604800 for 1 week. After passing this period, if a Cluster hasn't sale anything, its rank would be lowered gradually.
promoterAveragingPeriod uint32 Averaging period of a Promoter in seconds. Ex: 86400 for 1 day. Promoter's sale activities are averaged over last time per this period.
enabled bool True, if the Service is enabled.
id uint16 Service unique ID.
clustersCount uint16 Number of Clusters in this Service.
promotersCount uint16 Number of Promoters in this Service.
creator address Address of the Provider's wallet that created this Service.
fee uint256 Paid fee of this Service, if sale percent is selected.
consumer address Consumer contract address. The contract that sells a Service.
currency address Contract address of the token that Consumer used to sell things with it. If 0 supplied, native currency of the network is used, Ex: BNB.
DexRouter address DEX router contract address, used for getting currency price. Can be 0.
providerContact bytes32 Provider's email address.
clusterShare ClusterBreak Array of ClusterBreak structures, defines Cluster ranking stages. See below.
clusterLevelShare uint32[4] Share percentage of each rank of Cluster. Total must be 10000 (100%).

 

 
struct ClusterBreak//96 bits-1 slot
    {
        uint32 percentage;
        uint32 minPurchase;
        uint32 maxPurchase;
    }
						

 

Share percentage, if sale average of a Cluster is >= minPurchase < maxPurchase.

 

It is a percentage value that is casted into an integer from 0 to 10000. For example, 2156 means 21.56%.

 

getPromoterStatus

 

 
function getPromoterStatus(address wallet,uint16 serviceId) notContract external view returns (PromoterStatus memory)
						

 

Returns a PromoterStatus structure (see below) for a Promoter using his/her wallet address in a specified Service, by supplying a wallet address and a Service ID.

 

Name Type Description
wallet address Promoter's wallet address.
serviceId uint16 ID of the Service.

 

 
struct PromoterStatus{//10     
	bytes32 contact;// 1 slot
        bytes32 serviceName;// 1 slot
        uint32 saleCount;
        uint16 id;
        uint16 parentId;
        uint16 clusterId;
        uint16 serviceId;
        uint8 level;
        bytes16 nickName;
        bytes10 refCode;//80 bits 1slot
        uint256 income;
        uint256 totalIncome;
        uint256  directCommission;
        uint256  clusterCommission;
        uint256 saleAverage;
        uint256 registrationTime;
    }
						

 

Item Type Description
contact bytes32 Zero padded 32 bytes email address of the Promoter.
serviceName bytes32 Zero padded 32 bytes Service name, that this Promoter is registered in.
saleCount uint32 How many things the Promoter sold.
id uint16 Promoter's unique ID.
parentId uint16 Parent Promoter's ID.
clusterId uint16 Cluster ID that this Promoter is registered in.
level unit8 Level of this Promoter in its Cluster. 5 is the lowest and 1 is the highest.
nickName bytes16 Zero padded 16 bytes, nick name of the Promoter. Unique over a Service.
refCode bytes10 Zero padded 10 bytes, referral code of the Promoter.
income uint256 Unclaimed income in currency token of the Promoter.
totalIncome uint256 Total income in currency token of the Promoter since registration.
directCommission uint256 Direct sale commission percentage of the Promoter, casted into integer.
clusterCommission uint256 Cluster ranking commission of the Promoter, casted into integer.
saleAverage uint256 Sale average of the Promoter over time per averaging period of the Service.
registrationTime uint256 Time stamp of the Promoter registration.

 

getPromotersStatus

 

 
function getPromotersStatus(uint16 serviceId,uint16 cursor,uint16 count) external view returns (PromoterStatus[] memory _ps)
						

 

Returns array of PromoterStatus structure, using serviceId, cursor and count parameters. Refer getPromoterStatus function for more information.

 

getPromoterServices

 

 
function getPromoterServices(address wallet) external view returns ( uint16[] memory registeredServices)
						

 

Returns array of Service IDs, in which the wallet address is registered as a Promoter.

 

Name Type Description
wallet address Promoter's wallet address.

 

getProviderServices

 

 
function getProviderServices(address wallet) external view returns (uint16[] memory)
						

 

Returns an array of Service IDs according to a wallet address, this address must be a Provider wallet address.

 

Name Type Description
wallet address Provider's wallet address.

 

getCodeDiscount

 

 
function getCodeDiscount(bytes10 refCode) external view returns (uint256) 
						

 

Returns value of discount according to the supplied referral code. The return value is a percentage casted into uint256, from 0 to 10000 (100%).

 

Name Type Description
refCode address Zero padded 10 bytes, referral code of the Promoter.

 

getCodeCommission

 

 
function getCodeComission(bytes10 refCode) external view returns (uint256,uint256)
						

 

Returns sum of direct and Cluster commissions of a Promoter due to the supplied referral code as the first return parameter.

 

The second return value is the percentage of Service fee that must be paid by the Consumer contract if the Provider selected the Service registration fee to be paid as sale percentage, but if the Provider selected cash method, the value is 0.

 

Return values are percentages casted into uint256, from 0 to 10000 (100%).

 

Name Type Description
refCode address Zero padded 10 bytes, referral code of the Promoter.

 

Write Functions (Promoter)

 

registerPromoter

 

 
function registerPromoter(uint16 serviceId ,bytes10 refCode,bytes32 contact,bytes16 nickName) external notContract 
						

 

A Promoter can register itself in an arbitrary Service, by calling this function. If refCode is not supplied (set to 0), serviceId parameter is mandatory, in this way a new Cluster will be created and the Promoter will be set as the owner of this Cluster in the Service.

 

Upon supplying a refCode, serviceId parameter is ignored and the Promoter will be registered in the proper Service and Cluster that is specified by the refCode if the parent Promoter has enough capacity to accept it.

 

If the parent Promoter has no capacity or the Promoter is already registered by its wallet address or the supplied nick name exists, the function will revert!

 

Name Type Description
serviceId uint16 ID of the Service.
refCode bytes10 Zero padded 10 bytes, referral code of the Promoter.
contact bytes32 Optional; 32 bytes, zero padded email address of the Promoter. It is better to be encrypted due to user privacy.
nickName bytes16 Zero padded 16 bytes, nick name of the Promoter. The supplied nick name must be unique in a Service.

 

changePromoterContact

 

 
function changePromoterContact(bytes10 refCode,bytes32 contact) external 
						

 

Changes the Promoter's email address if necessary, using its referral code. Must be called from the Promoter's wallet address otherwise it will revert!

 

Name Type Description
refCode bytes10 Zero padded 10 bytes, referral code of the Promoter.
contact bytes32 32 bytes, zero padded email address of the Promoter. It is better to be encrypted due to user privacy.

 

withdrawIncome

 

 
function withdrawIncome(uint16 serviceId) external nonReentrant notContract
						

 

By calling this function, the Promoter can withdraw all of his/her income according to the supplied serviceId, in a single transaction. Must be called from the Promoter's wallet address otherwise it will revert!

 

Write Functions (Provider/Consumer)

 

registerServiceAndConsumer

 

 
function registerServiceAndConsumer(bytes32 serviceName,address consumer,
	ClusterBreak[5] calldata share,
	uint32[MIN_NODE_LEVEL-1] calldata levelShare,
	uint32 z1,uint32 z2,uint32 minDiscount,uint32 maxDiscount,
	uint32 clusterRelaxationPeriod,
	uint32 promoterAveragingPeriod,address currency,ServiceExtra calldata extra) external 
	payable nonReentrant notContract 
						

 

A Provider can create a new Service by calling this function. Emits OnServiceRegistered event. Read CryptuProEco® White Paper for more information.

 

Consumer contract must be a verified contract, so the Promotion Manager Ecosystem's administrators would check the contract code, if a bug or scam is detected, they are eligible to disable the Service without any prior notification!

 

If the currency token is a liquidity generator contract type or it applies any type of taxes on transactions, it is very important to exclude both, Consumer contract and Promotion Manager Contract from fee/tax, prior to register a Service, otherwise your Promoters would not be able to withdraw their incomes!

 

Name Type Description
serviceName bytes32 Zero padded 32 bytes Service name. Name must be unique in the Promotion Manager Ecosystem otherwise it reverts.
consumer address Address of the Consumer contract, which will use the Promotion Manager Ecosystem. Consumer contract must be a verified contract, so the Promotion Manager Ecosystem's owners would check the contract code, if a bug or scam is detected, they are eligible to disable the Service without any prior notification!
share ClusterBreak[5] Array of ClusterBreak structures, defines Cluster ranking stages. See ClusterBreak.
levelShare uint32[4] Share percentage of each rank of Cluster. Total must be 10000 (100%).
z1 uint32 Direct sale factor percentage. Must be <= 10000 (100%).
z2 uint32 Cluster sale factor percentage. Must be <= 10000 (100%).
minDiscount uint32 Minimum discount of referral codes. Must be < maxDiscount.
maxDiscount uint32 Maximum discount of referral codes. Must be > minDiscount.
clusterRankRelaxationPerid uint32 Relaxation period of Clusters in this Service in seconds, Ex: 604800 for 1 week. After passing this period, if a Cluster hasn't sale anything, its rank would be lowered gradually.
promoterAveragingPeriod uint32 Averaging period of a Promoter in seconds. Ex: 86400 for 1 day. Promoter's sale activities are averaged over last time per this period.
currency address Contract address of the token that Consumer used to sell things with it. If 0 supplied, native currency of the network is used, Ex: BNB.
extra ServiceExtra A ServiceExtra structure for Service optional values

 

 
struct ServiceExtra
    {
	address DexRouter;
        bytes32 website;
        bytes32 providerContact;
    }
						

 

Name Type Description
DexRouter address Optional; DEX router contract address, used for getting currency price. Can be 0.
website bytes32 Optional; Zero padded 32 bytes Provider's website address.
providerContact bytes32 Optional; Zero padded 32 bytes Provider email address.

 

changeServiceParameters

 

 
function changeServiceParameters(uint16 serviceId,address consumer,
         ClusterBreak[5] calldata share,
         uint32[MIN_NODE_LEVEL-1] calldata levelShare,
         uint32 z1,uint32 z2,uint32 minDiscount,
         uint32 maxDiscount,
         uint32 clusterRelaxationPeriod,
         uint32 promoterAveragingPeriod,
         ServiceExtra calldata extra) external nonReentrant notContract  
						

 

Provider can change its own Service by calling this function. Caller wallet address must be the Provider's wallet address, otherwise it reverts!

 

Name Type Description
serviceId unit16 Service ID.
consumer address Address of the Consumer contract, which will use the Promotion Manager Ecosystem. Consumer contract must be a verified contract, so the Promotion Manager Ecosystem's owners would check the contract code, if a bug or scam is detected, they are eligible to disable the Service without any prior notification!
share ClusterBreak[5] Array of ClusterBreak structures, defines Cluster ranking stages. See ClusterBreak.
levelShare uint32[4] Share percentage of each rank of Cluster. Total must be 10000 (100%).
z1 uint32 Direct sale factor percentage. Must be <= 10000 (100%).
z2 uint32 Cluster sale factor percentage. Must be <= 10000 (100%).
minDiscount uint32 Minimum discount of referral codes. Must be < maxDiscount.
maxDiscount uint32 Maximum discount of referral codes. Must be > minDiscount.
clusterRankRelaxationPerid uint32 Relaxation period of Clusters in this Service in seconds, Ex: 604800 for 1 week. After passing this period, if a Cluster hasn't sale anything, its rank would be lowered gradually.
promoterAveragingPeriod uint32 Averaging period of a Promoter in seconds. Ex: 86400 for 1 day. Promoter's sale activities are averaged over last time per this period.
extra ServiceExtra A ServiceExtra structure for Service optional values

 

useCode

 

 
function useCode(bytes10 refCode,uint32 buyCount, uint256 commissionAmount,uint256 fee) external nonReentrant; 
						

 

Just Consumer contract call this function, in order to inform the Promotion Manager Ecosystem, that a successful buy operation is finished. It emits OnCodeUsed event.

 

The Consumer contract, must report refCode used, buy count of goods/service, transferred commission amount of the Promoter, transferred fee amount of the Promotion Manager Ecosystem (if sale percent is selected at Service registration time). Before calling this function, Consumer contract must transfer Promoter's commission amount and Promotion Manager Ecosystem's fee (if sale percent is selected at Service registration time), to the Promotion Manager contract.

 

Consumer contract must be a verified contract, so the Promotion Manager Ecosystem's owners would check the contract code, if a bug or scam is detected, they are eligible to disable the Service without any prior notification!

 

If the currency token is a liquidity generator contract type or it applies any type of taxes on transactions, it is very important to exclude both, Consumer contract and Promotion Manager contract from fee/tax prior to register a Service, otherwise your Promoters would not be able to withdraw their incomes!

 

Name Type Description
refCode bytes10 Zero padded 10 bytes, referral code of the Promoter.
buyCount uint32 Count of sold goods/service.
commissionAmount uint256 Transferred amount of Promoter's commission.
fee uint256 Transferred amount of Promotion Manger Ecosystem fee (if sale percent is selected at Service registration time), otherwise it is 0.

 

Write Functions (Owner)

 

setServiceRegistrationParams

 

 
function setServiceRegistrationParams(uint256 fee,uint32 feePercent,address feeReceiver ) external onlyOwner
						

 

Promotion Manager Ecosystem’s owner can set the Service registration fee (for cash option), fee percent (for sale percentage option) and fee receiver address.

 

Name Type Description
fee uint256 Service registration fee in Wei.
feePercent uint32 Fee percentage, (0 to 10000).
feeReceiver address Fee receiver address.

 

enableService

 

 
function enableService(uint16 serviceId) external onlyOwner
						

 

Promotion Manager Ecosystem’s owner can enable a Service every time.

 

Name Type Description
serviceId uint16 Service ID.

 

disableService

 

 
function disableService(uint16 serviceId) external onlyOwner
						

 

Promotion Manager Ecosystem’s owner can disable a Service every time.

 

Name Type Description
serviceId uint16 Service ID.

 

findService

 

 
function findService(bytes32 serviceName) external view onlyOwner returns (uint16)
						

 

Promotion Manager Ecosystem’s owner can use this function to find Service ID by its name.

 

Name Type Description
serviceName bytes32 Zero padded 32-bytes Service name.

 

withdrawFee

 

 
function withdrawFee(uint16 serviceId) external onlyOwner
						

 

Promotion Manager Ecosystem’s owner can withdraw the collected Service registration fee.

 

Emits OnFeeWithdrawn event.

 

Name Type Description
serviceId uint16 Service ID.

 

setPromotionManagerLimits

 

 
function setPromotionManagerLimits(uint16 maxServiceCount,uint16 maxClusterCount,uint16 maxPromoterCount) external onlyOwner
						

 

Promotion Manager Ecosystem’s owner can change the Promotion Manager Ecosystem size upon the network condition. Use it carefully! Check all current Services, Clusters and Promoters count.

 

Name Type Description
MaxServiceCount uint16 Maximum Services count can be created on the Promotion Manager Ecosystem. Default: 100.
maxClustersCount uint16 Maximum Clusters count can be created per Service on the Promotion Manager Ecosystem. Default: 1000.
maxPromoterCount uint16 Maximum Promoters count can be created per Service on the Promotion Manager Ecosystem. Default: 15000.

 

Events (Promoter)

 

OnPromoterRegistered

 

 
event OnPromoterRegistered(bytes10  referralCode);
						

 

Promoter is registered.

 

Emitter: registerPromoter.

 

OnIncomeWithdrawn

 

 
event OnIncomeWithdrawn(address wallet,address currency,uint256 amount);
						

 

Promoter withdrew his/her income successfully.

 

Emitter: withdrawIncome.

 

Events (Provider)

 

OnServiceRegistered

 

 
event OnServiceRegistered(uint256 serviceId);
						

 

Provider registered a new Service.

 

Emitter: registerServiceAndConsumer.

 

OnCodeUsed

 

 
event OnCodeUsed(bytes10 refCode, uint256 clusterTotalSale,uint256 clusterSaleAverage,uint256 clusterScore);
						

 

Referral code used to buy goods/services.

 

Emitter: useCode.

 

Events (Owner)

 

OnFeeWithdrawn

 

 
event OnFeeWithdrawn(address currency,uint256 amount);
						

 

Service registration fee is withdrawn.

 

Emitter: withdrawFee.

 

Contract Roles

 

Role Description
Owner (onlyOwner) The Promotion Manager smart contract owner.
Promoter A person with a wallet address that wants to be a Promoter in Promotion Manager Ecosystem. Every goods/services that be sold by the Promoter's referral code, make some income for him/her according to the selected Service.
Provider A person/company with a wallet address, which wants his/her/its goods/services to be sold by promoters.
Consumer A smart contract that is developed by the Provider to sell goods/services on a smart chain using an interface to the Promotion Manager smart contract.
Buyer A person with a wallet address that wants to buy goods/services from Provider by using a Promoter's referral code, upon using this code he/she benefits from discount. A buyer interacts with the Consumer smart contract.

 

Role Description

 

Owner

 

0xad9d97fc7bf0ac6dc68d478dcb3709454519b358

 

Address controlled by gnosis multisignature contract with a threshold of 3/4

 

Functions

 

registerServiceAndConsumer - Provider

 

 
function registerServiceAndConsumer(bytes32 serviceName,address consumer,
	ClusterBreak[5] calldata share,uint32[MIN_NODE_LEVEL-1] calldata levelShare,
	uint32 z1,uint32 z2,uint32 minDiscount,uint32 maxDiscount, uint32 clusterRelaxationPeriod,
        uint32 promoterAveragingPeriod,address currency,ServiceExtra calldata extra) external payable nonReentrant notContract   
    {
        bool _payETH;
        {//scope: checks
            //adding service and its operartor
            require( _currentServiceId<=_maxServiceCount,"Too many services!");
            require(serviceName!=0,"Service name not supplied!");
            require((z1<=10000)&&(z2<=10000),"Invalid z1 or z2!");
            require(maxDiscount<= MAX_SERVICE_DISCOUNT,"Discount exceeds limit!");
            require(maxDiscount>minDiscount,"Max discount< Min discount!");       
            require(((clusterRelaxationPeriod>=MIN_TIME_SLICE)&&(clusterRelaxationPeriod <=MAX_RELAXATION_PERIOD)),
				"clusterRelaxationPeriod not in range!");
            require((promoterAveragingPeriod>=MIN_TIME_SLICE),"promoterAveragingPeriod not in range!");
            uint _totalShare;
            for(uint i;i<(MIN_NODE_LEVEL-1);)
            {
                _totalShare+=levelShare[i];
                unchecked{++i;}//gas opt
            }
            require(_totalShare==10000,"Total level shares != 10000!");
            require(share[0].percentage<=10000,"Cluster share values > 10000!");
            require(share[1].percentage<=10000,"Cluster share values > 10000!");
            require(share[2].percentage<=10000,"Cluster share values > 10000!");
            require(share[3].percentage<=10000,"Cluster share values > 10000!");
            require(share[4].percentage<=10000,"Cluster share values > 10000!");
            require(share[0].maxPurchase>share[0].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[1].maxPurchase>share[1].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[2].maxPurchase>share[2].minPurchase,"MaxPurchase < MinPurchase!!");
            require(share[3].maxPurchase>share[3].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[4].maxPurchase>share[4].minPurchase,"MaxPurchase < MinPurchase!");
        }
        uint16 _serviceId =_findServiceByName(serviceName);// (stringToBytes32(serviceName));
        if (_serviceId!=0)//the service is regestered before
        {
            //no thing to do
            revert("Service already exists!");
        }else // no such a this service is registered
        {
            //provider selected the ETH payment method
            //this is a new service creation so the caller must pay the registration Fee
            if(msg.value!=0)
            {
                _payETH=true;
                require(msg.value==_serviceRegistrationFee,"Service registration fee is not enough!");   
                //transfering to fee receiver
                payable(_feeReceiver).transfer(_serviceRegistrationFee);
            }          
            _currentServiceId=_lowgas_inc(_currentServiceId);// gas opt
            _providers[msg.sender].wallet=msg.sender;//add this as new provider that owns this service
            _providers[msg.sender].serviceIds.push(_currentServiceId);//by array
            Service storage _newService=_services[_currentServiceId];
            _newService.id=_currentServiceId;
            _newService.registered=true;
            _newService.enabled=true;
            _newService.name=serviceName; 
            _newService.creator=msg.sender;//set the caller as the service creator                    
            //adding the consumer
            _newService.consumer=consumer;
            _newService.clustersCount=0;
            //coping cluster share values
            _newService.clusterShare[1]=share[0];
            _newService.clusterShare[2]=share[1];
            _newService.clusterShare[3]=share[2];
            _newService.clusterShare[4]=share[3];
            _newService.clusterShare[5]=share[4];
            //copying cluster level share values
            for(uint8 i=1;i<(MIN_NODE_LEVEL);)
            {
                 _newService.clusterLevelShare[i]=levelShare[i-1];
                 unchecked{++i ;}//gas opt
            }
            //setting z factors
            _newService.z1=z1;
            _newService.z2=z2;
            //setting disounts
            _newService.minDiscount=minDiscount;
            _newService.maxDiscount=maxDiscount;
            _newService.promoterAveragingPeriod=promoterAveragingPeriod;
            _newService.clusterRankRelaxationPeriod=clusterRelaxationPeriod;
            _newService.currency=currency;
            _newService.payETH=_payETH;
            _newService.DexRouter=extra.DexRouter;
            _newService.website=extra.website;
            _newService.providerContact=extra.providerContact;
            emit OnServiceRegistered(_currentServiceId);    
        }
    }
						

 

A Provider, calls this function by his/her wallet to create a Service on the Cryptu Promotion Manager Ecosystem (CryptuProEco®).

 

changeServiceParameters - Provider

 

 
function changeServiceParameters(uint16 serviceId,address consumer,
	ClusterBreak[5] calldata share,uint32[MIN_NODE_LEVEL-1] calldata levelShare,
	uint32 z1,uint32 z2,uint32 minDiscount,uint32 maxDiscount, uint32 clusterRelaxationPeriod,
        uint32 promoterAveragingPeriod,
        ServiceExtra calldata extra) external nonReentrant notContract   
    {
        require(_isServiceRegistered(serviceId),"Invalid service Id!");
        Service storage _currentService=_services[serviceId];  
        {//scope: checks
            require(_currentService.creator==msg.sender,"Unauthorized!");   
            // require(serviceName!=0,"Service name not supplied!");
            require((z1<=10000)&&(z2<=10000),"Invalid z1 or z2!");
            require(maxDiscount<= MAX_SERVICE_DISCOUNT,"Discount exceeds limit!");
            require(maxDiscount>minDiscount,"Max discount< Min discount!");            
            require(((clusterRelaxationPeriod>=MIN_TIME_SLICE)&&(clusterRelaxationPeriod <=MAX_RELAXATION_PERIOD)),"clusterRelaxationPeriod not in range!");
            require((promoterAveragingPeriod>=MIN_TIME_SLICE),"promoterAveragingPeriod not in range!");
            uint256 _totalShare;
            for(uint256 i;i<(MIN_NODE_LEVEL-1);)
            {
                _totalShare+=levelShare[i];
                unchecked{++i;}
            }
            require(_totalShare==10000,"Total level shares != 10000!");
            require(share[0].percentage<=10000,"Cluster share values > 10000!");
            require(share[1].percentage<=10000,"Cluster share values > 10000!");
            require(share[2].percentage<=10000,"Cluster share values > 10000!");
            require(share[3].percentage<=10000,"Cluster share values > 10000!");
            require(share[4].percentage<=10000,"Cluster share values > 10000!");
            require(share[0].maxPurchase>share[0].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[1].maxPurchase>share[1].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[2].maxPurchase>share[2].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[3].maxPurchase>share[3].minPurchase,"MaxPurchase < MinPurchase!");
            require(share[4].maxPurchase>share[4].minPurchase,"MaxPurchase < MinPurchase!");
        }  
	//checks provider existance 
        //set the consumer contract address
        _currentService.consumer=consumer;
        //copying cluster share values
        _currentService.clusterShare[1]=share[0];
        _currentService.clusterShare[2]=share[1];
        _currentService.clusterShare[3]=share[2];
        _currentService.clusterShare[4]=share[3];
        _currentService.clusterShare[5]=share[4];
        //copying cluster level share values
        for(uint8 i=1;i<(MIN_NODE_LEVEL); )
        {
            _currentService.clusterLevelShare[i]=levelShare[i-1];
            unchecked{++i;}//gas opt
        }
        _currentService.z1=z1;
        _currentService.z2=z2;
        //setting disounts
        _currentService.minDiscount=minDiscount;
        _currentService.maxDiscount=maxDiscount;        
        _currentService.promoterAveragingPeriod=promoterAveragingPeriod;
        _currentService.clusterRankRelaxationPeriod=clusterRelaxationPeriod;
        _currentService.DexRouter=extra.DexRouter;
        _currentService.website=extra.website;
        _currentService.providerContact=extra.providerContact;
        //currency is not changeable     
    }
						

 

The changeServiceParameters can be called by a Provider to change its Service parameters.

 

useCode – Provider

 

 
function useCode(bytes10 refCode,uint32 buyCount, uint256 commissionAmount,uint256 fee) external nonReentrant 
    {
        //updates the state of PM due to service sales
        //checking code validity
        Referral memory _referral= _referrals[refCode];
        require ((_referral.serviceId!=0),"Invalid code!");//gas opt
        require ((_referral.clusterId!=0),"Invalid code!");
        require((_referral.promoterId!=0),"Invalid code!");
        require(_services[_referral.serviceId].consumer==msg.sender,"Invalid consumer!");//gas  opt
        require(_services[_referral.serviceId].enabled,"Service disabled!");
        //getting service, cluster and promoter
        Service  storage _currentService = _services[_referral.serviceId];
        Cluster  storage _currentCluster=_currentService.clusters[_referral.clusterId];
        Promoter storage _currentPromoter=_currentService.promoters[_referral.promoterId]; 
        //increasing the payed fee value of this service
        _currentService.fee=_lowgas_add_256(_currentService.fee,fee); //_currentService.fee+=fee;           
        _currentPromoter.income=_lowgas_add_256(_currentPromoter.income,commissionAmount); 
        _currentPromoter.totalIncome= _lowgas_add_256(_currentPromoter.totalIncome,commissionAmount);
        //increase the sale count of this promoter
        _currentPromoter.saleCount=_lowgas_add_32(_currentPromoter.saleCount,buyCount); 
        //increase total sale of this cluster
        _currentCluster.totalSale=_lowgas_add_32( _currentCluster.totalSale,buyCount); 
        //updating direct sale percentage
        //z1*f1
        ( _currentPromoter.directCommission,_currentPromoter.saleAverage)=(_calcPromoterDirectCommission(_currentService, _currentPromoter));
        //updating  promoter's cluster commission
        uint256 _saleAverage;
        uint8 _rank;
        (_currentPromoter.clusterCommission ,_saleAverage ,_rank)=_calcPromoterClusterComission(_currentService,_currentCluster,
			 _currentPromoter);
        //the cluster section 
        //gas opt-less gas 
        uint256 _clusterScore= _updateClusterRankAndAverage2(_currentService,_currentCluster, _saleAverage, _rank); 
        emit OnCodeUsed(refCode,_currentCluster.totalSale,_currentCluster.saleAverage,_clusterScore);
    }
						

 

A Provider must call this function in the Buy function of his/her Consumer contract to tell the Promotion Manager, that goods/services have been sold by a Promoter referral code. For more information see: How to Implement Promotion Manager in My Consumer Contract.

 

registerPromoter – Promoter

 

 
function registerPromoter(uint16 serviceId ,bytes10 refCode,bytes32 contact,bytes16 nickName) external notContract 
     {
	require(_currentServiceId!=0,"No service registered!");
        require(_services[serviceId].enabled,"Service disabled!");
        bytes10  _code;
        _code =  _registerPromoter(serviceId,refCode,contact,nickName);
        emit OnPromoterRegistered(_code);
     }
						

 

Callable by a Promoter to register himself/herself in a Service.

 

changePromoterContact – Promoter

 

 
function changePromoterContact(bytes10 refCode,bytes32 contact) external 
    {
        //changes a promoter's contact data
        Referral memory _referral=_referrals[refCode]; //checking the validity of ref code
        require ((_referral.serviceId!=0)&&(_referral.clusterId!=0)&&(_referral.promoterId!=0),"Invalid code!");       
        //it is a valid code           
        Service storage _currentService = _services[_referral.serviceId];
        Promoter storage _currentPromoter=_currentService.promoters[_referral.promoterId];
        require(_currentPromoter.wallet==msg.sender,"Not authorized!");
        _currentPromoter.contact=contact;//set the contact data
    }
						

 

For a registered Promoter to change his/her email address. For privacy, it is recommended to send encrypted email address into this function that is not readable by others in the block explorer of the smart chain!

 

withdrawIncome – Promoter

 

 
function withdrawIncome(uint16 serviceId) external nonReentrant notContract
    {
        //promoter claims his/her own income
        require(_isServiceRegistered(serviceId),"Invalid service Id!");
        Service storage _currentService=_services[serviceId];
        require (_isPromoterRegistered(_currentService,msg.sender),"Not registered in this service!");
        Promoter storage _currentPromoter= _currentService.promoters[_currentService.wallets[msg.sender].promoterId];
        require(_currentPromoter.income!=0,"Nothing to withdraw!");
        uint256 _amount= _currentPromoter.income;
        //setting the income to 0
        _currentPromoter.income=0;
	//Transfer money to msg.sender
        if  (_currentService.currency==address(0))
        {
            //native 
            address payable _to= payable(msg.sender);
            (bool sent,) = _to.call{value: _amount}("");
            require(sent, "Failed to send Ether");
        }else 
        {
            //token
           
            IERC20  _currencyToken=IERC20(_currentService.currency);
            _currencyToken.safeTransfer(msg.sender, _amount);
        }
         emit OnIncomeWithdrawn(msg.sender,_currentService.currency,_amount) ;
    }
						

 

A registered Promoter can call this function from the wallet used to register himself/herself, to withdraw the income of promotions.

 

setServiceregistrationParams – Owner

 

 
function setServiceRegistrationParams(uint256 fee,uint32 feePercent,address feeReceiver ) external onlyOwner
     {
	//sets the service registration fee and receiver address
	_setServiceRegistrationParams(fee,feePercent, feeReceiver);
     } 
						

 

Only the Owner of Promotion Manager contract can call this function to change the Service registration fee parameters.

 

enableService – Owner

 

 
function enableService(uint16 serviceId) external onlyOwner
    {
        //enables the service
        require(_services[serviceId].registered,"Service not registered!");
        _services[serviceId].enabled=true;
    }
						

 

The Owner can enable a registered Service.

 

disableService – Owner

 

 
function disableService(uint16 serviceId) external onlyOwner
    {
        //disables the service
       require(_services[serviceId].registered,"Service not registered!");
        _services[serviceId].enabled=false;
    }
						

 

The Owner can disable a registered Service.

 

findService – Owner

 

 
function findService(bytes32 serviceName) external view onlyOwner returns (uint16)
    {
        //owner can find service id by name
        return _findServiceByName(serviceName);
    }

						

 

The Owner can find a registered Service ID, by its name.

 

withdrawFee – Owner

 

 
function withdrawFee(uint16 serviceId) external onlyOwner
    {
        //promoter claims his/her own income
        require(_isServiceRegistered(serviceId),"Invalid service Id!");
        Service storage _currentService=_services[serviceId];
        require (_currentService.fee!=0,"Nothing to withdraw!");
     
        uint256 _amount= _currentService.fee;
        //setting the fee to 0
        _currentService.fee=0;
	// Transfer money to msg.sender
        if  (_currentService.currency==address(0))
        {
            //native 
            address payable _to= payable(msg.sender);
            (bool sent,) = _to.call{value: _amount}("");
             require(sent, "Failed to send Ether");
        }else 
        {
            //token
           
            IERC20  _currencyToken=IERC20(_currentService.currency);
            _currencyToken.safeTransfer(msg.sender, _amount);
        }
         emit OnFeeWithdrawn(_currentService.currency,_amount) ;
    }
						

 

The Owner can withdraw the collected Service registration fee.

 

setPromotionManagerLimits- Owner

 

 
function setPromotionManagerLimits(uint16 maxServiceCount,uint16 maxClusterCount,uint16 maxPromoterCount) external onlyOwner
    {
        //sets service, cluster , promoters max count
        //use it carefully!
        require(_maxServiceCount>=_currentServiceId,"Current service count is more!");
        _maxServiceCount=maxServiceCount;
        _maxClusterCount=maxClusterCount;
        _maxPromoterCount=maxPromoterCount;
    }
						

 

The Owner can set the maximum size of the Promotion Manager Ecosystem.

 

How to Implement Promotion Manager in My Consumer Smart Contract?

 

1- Adding ICryptuPromotionManager Interface

 

Your Consumer contract must import the ICryptuPromotionManager.sol like the below code:

 

Import "ICryptuPromotionManager. Sol";

 

Then, add below code to the Consumer contract body, in its public section, to define instance of Promotion Manager contract and its interface:

 

 
contract Tester is ReentrancyGuard,Ownable{
//testbench for CryptuPromotionManager
address private _promotionManager;
address private _currency;
ICryptuPromotionManager public promotionManager;//Promotion Manager Interface
IERC20 public currencyToken;// Interafce of currency token
						

 

Add Promotion Manager contract address parameter into Consumer contract constructor body, or define it statically in your code:

 

 
constructor (address promoManager,address currency) Ownable(msg.sender)
   {
        _currency=currency;//currency token address that you want to sell your goods/services by it, If you want to sell by native currencies(ETH,BNB,…) just pass 0;
        _promotionManager=promoManager;//put  Promotion Manager address to private variabe.
        //set the intaerface to the address
        promotionManager=ICryptuPromotionManager(_promotionManager);
   }
						

 

2- Using the Promotion Manager Interface

 

The Consumer contract, must have a Buy function, for example this function is buyService, and your customers call this function by their wallets to purchase something from your store. To use Promotion Manager feature in your Consumer contract, your Buy function must pass the referral code parameter like this:

 

 
function buyService(uint32 count,bytes32 refCode) external payable 
						

 

Purchase page of your store website must have a referral code text box, in which, your customer can enter their referral code to get some discount. Your website code must convert that referral code into 10 Bytes code and pass it to the Buy function by web3 interface of MetaMask™ wallet. Java Script code snippet to do it:

 

 
function zeroLeading(str,count)
    {
	var pad=new String;
	return pad.padStart(count-str.length,'0')+str
    }
function encodeRefCode(strcode)
    {
	let arr=strcode.split("-")
	let r
	if(arr.length==4)
    {
	let s=Number(arr[0]).toString(16)
	s=zeroLeading(s,4)
	let c=Number(arr[1]).toString(16)
	c=zeroLeading(c,4)
	let p=Number(arr[2]).toString(16)
	p=zeroLeading(p,4)
	let code=Number(arr[3]).toString(16)
	code=zeroLeading(code,8)
	r="0x"+s+c+p+code
    }
	else
	r="0x00000000000000000000"
	return r 
    } 
						

 

A referral code has below format:

 

ServiceID-ClusterID-PromoterID-RandomCode

 

For example: 1-1-1-351687

 

This code must be packed into a Bytes10 variable (Ex: 0x00010001000100155ef3) and then be passed to the Buy function, so the above JS snippet, can do it for you.

 

The Buy function body must have the below code in its body. It should be payable if you want to use native currencies (ETH, BNB, etc.):

 

 
function buyService(uint32 count,bytes32 refCode) external payable 
    {
	uint256 _amount=count*SERVICE_PRICE;//your goods/services cost
	/*asking the Promotion Manager, how much commission must be paid to the Promoter, who his/her referral code is used
	in this purchase and if there must be a service registration fee to be paid to the Promotion Manager Ecosystem*/
	(uint256 _promoterPercent, uint256  _feePercent)=promotionManager.getCodeComission(refCode); 
	//getting commision percentage from te PM
	//calculatiing the amount of Promoter commission 
	uint256 _promoterCommission=(_promoterPercent*_amount)/10000;
	//calculatiing the amount of service registration fee(if you want to pay the fee by your sale percentage, otherwise this value is 0)  
	uint256 _fee=(_feePercent*_amount)/10000;
	if (_currency==address(0))
    {
	//for native currencies only
	//if you use token currencies, remove these lines
	/********************************************************************/
	//transfering buy amount into this contract
	require(_amount==msg.value,"Not enough ETH payed!");
	//transfering the Promoter commission to the Promotion Manager
	address payable _to= payable(_promotionManager);
	(bool _sent,) = _to.call{value:_promoterCommission}("");
	require(_sent, "Failed to send commission");
	if(_fee!=0)
    {
        //there is a service registration fee that must be paid  from sale amount
        (_sent,) = _to.call{value:_fee}("");
        require(_sent, "Failed to send fee!");
    }	
	/********************************************************************/
    }else 
    {
        //for token currencies
        //if you use native currencies (ETH, BNB,...),  remove these lines
        /********************************************************************/
        //transfering buy amount into this contract
        currencyToken.safeTransferFrom(address(msg.sender), address(this),  _amount);
        //transfering the Promoter commission to PM
        currencyToken.safeTransfer(_promotionManager, _promoterCommission);
        if(_fee!=0) 
        {
        //there is a service regitration fee that must be paid  from sale amount
        //transfering fee to the Promotion Manager
        currencyToken.safeTransfer(_promotionManager, _fee);
        }
	/********************************************************************/
    }
	/*using the referral code, the consumer must call the Promotion Manager useCode function after 
	finishing the commission and fee transfers*/
	promotionManager.useCode(refCode,count,_promoterCommission,_fee);
	//emitting the event 
	emit OnCommisionTransfered
    }
						

 

Attention: Consumer contract must be a verified contract, so the Promotion Manager Ecosystem’s administrators would check the contract code, if a bug or scam is detected, they are eligible to disable the Service without any prior notification!

CryptuProEco® Instruction


 

 

CryptuProEco® or Cryptu Promotion Ecosystem is an unique, professional and comprehensive platform under Cryptu.io without any other example in the crypto world that you may enter it for services or promoters which will be described later. In this platform, the INCOME is the GOAL. If you have a business, you may think of merchandising or extending. Else you may want to introduce others and receive your COMMISSION.

Two fundamental sections of the CryptuProEco® consist of services and promoters. In other word if you have your own business, you may register as a new service else you may would like to register as a new promoter.

 

Promoter

 

The promoters are the people who try to reach potential investors. Indeed, they increase excitement surrounding investment and generate additional revenue.

 

Service

 

In a word, a service is a business. The owner of a company may like to extend his/her business. You can register your company/business as a service and reach the top promoters. They can help you to absorb the customers, so your revenue will be promoted. Then you should pay the promoters’ commission.

The main part of our platform has been named “Promotion Manager”. The first step is to connect your wallet (Fig. 1). Our registration is free of charge for the promoters.

 

Fig. 1: Connecting Wallet.

 

You may see a column in the left-hand side of the CryptoProEco® webpage. The first item is “Tops“ (Fig. 2).

 

Fig. 2: Tops.

 

This item has two sub-items:

 

• Top Services (Providers)

• Top Promoters

 

Top Services

 

The top services may be seen in Fig. 3. This table shows the list of businesses which are registered in the CryptuProEco® and they are sorted based on their ranks.

 

Fig. 3: Top Services.

 

The shown top services table consist of several columns as described in the following table:

 

Column Title Description
Name The name (or title) of the service or business is written here.
Rank The level of the desired service may be shown in the rank place based on total sale count.
Sale Count The amount of the providers’ articles that is traded in the CryptuProEco®.
Total Income ($) The revenue of the top services in $ till now.
Total Income (Crypto) The revenue of the top services in cryptocurrency till now by the currencies in which they are acceptable by the providers. These currencies are set during the service registration (refer sec. 5-11).
Promoter Count The number of the promoters in which they are trying to reach investors and/or the customers for the desired top services.
Currency The acceptable currency of the desired top services.
Website The website of the top services in which registered in the CryptuProEco®.

 

Top Promoters

 

In this section, the list of top promoters is shown as Fig. 4. The table shows the top promoters’ situation which are registered in the CryptuProEco®

 

Fig. 4: Top Promoters.

 

The shown top promoters table consist of several columns as described in the following table:

 

Column Title Description
Nickname The title that each promoter has chosen for themselves during the registration period.
Level The level of each promoter is specified by his/her activity (Refer to the CryptuProEco® White Paper).
Sale Average The average of the sold products by the promoter per each month.
Sale Count The amount of the articles that is traded by each promoter.
Income ($) The income of each promoter in $.
Income (Crypto) The income of each promoter in Cryptocurrency.
Commission (%) Percentage of the receiving commission of each promoter from the total commission.

 

Register New Promoter

 

Each promoter should have been registered at the beginning. Their information must enter in the CryptuProEco® related section (Fig. 5). These fields should fill very carefully by each promoter.

 

Fig. 5: Register New Promoter.

 

New promoter registration consist of fields as described in the following table:

 

Field Title Description
Service The kind of service is selected here. If you are the first promoter of a business, you will choose that specific company (or business). Else and if other promoter has introduced a business, so you will have a referral code and you should enter it in the related box. So, you will be the other promoter of that introduced business automatically and you are completing the cluster with others (Refer to the CryptuProEco® White Paper).
Referral The referral code that you have received from other promoters and your team (you and other promoters) are trying to complete a cluster (Refer to the CryptuProEco® White Paper).
Nickname A nickname that you choose during the registration period. You will be known by this nickname.
Email Your email should be written here.

 

You should press “Submit” after completing all fields. Then you are a NEW PROMOTER in a cluster

 

Your Promotions

 

Your promotions information will be shown as Fig. 6 till Fig. 12.

 

Fig. 6: Your Promotions-Part 1.

 

The shown your promotions-part1 table consist of several columns as described in the following table:

 

Column Title Description
Nickname Your nickname that has been chosen during the registration period, is shown here. You will be known by this nickname.
Referral Your referral code that is unique. You may send it to others that they become other promoters. You can be a head of the cluster in this way and receive more commission.
Email Your email which is declared during registration period.
Joined The date of your registration.
Balance It is the current account balance. It means at the moment you can have this amount of currency.

 

The other promotion data may be seen in the Fig. 7 as follows.

 

Fig. 7: Your Promotions-Part 2.

 

As it is shown in the Fig. 7, the promotion that is gained in various services, is summarized here. Each part is described as follows:

 

• Service:

The various service(s) that you are its (or their) promoters, is listed here as drop box.

 

• Total Clusters:

Here is the information of all clusters of the selected service. This table will be changed by selecting the various services.

- Count:

The number of clusters which is formed in the selected service.

- Sale:

The number of the total sales of the selected service (by the total clusters).

- Average:

The average of the total sold products of the selected service per each month.

- Income (Crypto):

Total income of the selected service in cryptocurrency.

- Income ($):

Total income of the selected service in $.

 

• Your Cluster:

Here is the information of each cluster, that you are its service member and you have chosen from the service drop box.

- Owner:

It is the nickname of the cluster owner.

- Promoters:

The number of promoters of the selected cluster.

- Sale:

The number of products that your cluster has traded till now in the selected service.

- Average:

The average of the sold products (in the selected service) by the promoter per each month.

- Income (Crypto):

Your cluster income in cryptocurrency for the selected service.

- Income ($):

Your cluster income in $ for the selected service.

 

• Your Promotions:

Here is the information of your activity in each service as follows:

- Sale:

The amount of the products that you have sold till now in the selected service.

- Average:

The average of the sold products (in the selected service) by yourself per each month.

- Income (Crypto):

Your own income in cryptocurrency for the selected service from the beginning. It may be different to the balance.

- Income ($):

Your own income in $ for the selected service from the beginning.

- Direct Commission:

It is your own commission in % from the total trading of the selected service.

- Cluster Commission:

The percentage of the commission that members of a cluster have received from the total trading.

- Total Commission:

It is the total commission that all promoters have received.

 

• Your Cluster's Diagram:

The cluster that you are formed, may be shown as Fig. 8.

 

Fig. 8: Your Promotions-Part 3.

 

As it is shown in Fig. 8, you can see the situation of your cluster that is formed in the selected service.

 

• Cluster Ranking:

The ranking of the service clusters, for the selected service, is shown in Fig. 9. It can be a criterion to find if how many percentages of clusters are in rank 1, 2, 3, 4 or 5.

 

Fig. 9: Your Promotions-Part 4.

 

• Your Cluster's History:

The history of your cluster in the selected service is shown in Fig. 10 as follows:

 

Fig. 10: Your Promotions-Part 5.

 

In this graph, history of the rank of your cluster, history of the sale count, history of the sale average and history of the number of the promoters may be seen simultaneously.

 

• Your History:

Here is your performance history which may be shown in Fig. 11.

 

Fig. 11: Your Promotions-Part 6.

 

In this graph you can see your own performance in your cluster of the selected service. The cluster commission (%) based on the total sale, your own direct commission (%), the number of articles that you have traded and the sale average are shown in this graph.

 

• Your Contact and Withdraw:

Your contact information as your Nickname and Email is shown in the Fig. 12.

 

Fig. 12: Your Promotions-Part 7.

 

Also, you can withdraw your balance as you can check it at the bottom of the Fig. 6.

 

Register New Service

 

You can register your service or business to promote your job and income. The promoters may select your service to promote it dramatically. As it is seen in Fig. 13, you need some information to complete the service registration.

 

Fig. 13: Register New Service.

 

New service registration consist of fields as described in the following table:

 

field Title Description
Name The name of your service is written here.
Consumer It is the wallet address of the service owner. The network of your wallet address should be acceptable by our side like BNB, ETH, BTC etc.
Cluster Share You can define the share of the cluster in ------. In other word, the cluster has its own rank that you can set it here (Refer to the CryptuProEco® White Paper).
Level Share Each cluster has 4 levels that each level has its own share (or its own percentage). You can write each level percentage here (Refer to the CryptuProEco® White Paper).
Z1 (%) Direct Commission Weight Factor in percent.
Z2 (%) Cluster Commission Weight Factor in percent.
Min Discount (%) It is the minimum discount that you (as a service owner) set here in percentage of the total selling.
Max Discount (%) It is the maximum discount that you (as a service owner) set here in percentage of the total selling. It is for banning your total discount from a specific number. When you set Z1 and Z2, it is probable the discount becomes very high that is not acceptable by your side. Here you set a ban that your maximum discount be under your control.
Averaging Period (in second) It is the number that you define the averaging period for the promoters (please refer to the item 2-3).
Relaxation Period (in second) The commission of the promoters is calculated based on the averaging sale (please refer to the item 2-3) that is calculated based on the averaging period. We have considered a relaxation period that the promoters’ effort will not be ruined if he/she does not sell for a period of time. In other word the averaging sale will not become low for a period of time. So, the motivation stays high for this time.
Currency Here is the contract address of your acceptable currency. It may be the contract address of $FARTY, BNB, BTC etc.
Fee Payment You can select the commission of each promoter that you should pay, as one of the following ways:

A) 0.1 BNB

B) 1% of Sale
Defaults You may change the values to their default via this button.
Submit You should finalize your registration after filling all fields. So please press the “Submit” button when you are sure that you have filled all fields.

 

Your Provided Services

 

After the service(s) registration, you can see their situation as Fig. 14:

 

Fig. 14: Your Provided Services.

 

Your provided services consist of fields as described in the following table:

 

field Title Description
Service You can select one of the registered services here.
Cluster You can choose each cluster which are in your service(s).
Promoter Each promoter with their IDs is shown here. You can choose each promoter who is active in your service.

 

• Service Parameters:

You may select each of your own registered service, the selective cluster ID and the selective promoter ID as shown in Fig. 15. The parameters of your registered service(s) can be changed here. In other word you can trace your service and change their parameters.

 

Fig. 15: Service Parameters.

 

Services parameters consist of fields as described in the following table:

 

field Title Description
Consumer It is the wallet address of the registered service owner. The network of your wallet address should be acceptable by our side like BNB, ETH, BTC etc.
Cluster Share You can define the share of the cluster of the registered service in ------. In other word, the cluster has its own rank that you can change it here (refer to the marketing white paper).
Level Share Each cluster has 4 levels that each level has its own share (or its own percentage). You can change each level percentage here (that is set in "Level Share" of the register new getServiceStatus).
Z1 (%) Direct Commission Weight Factor in percent.
Z2 (%) Cluster Commission Weight Factor in percent.
Min Discount (%): It is the minimum discount that you (as a service owner) can change here in percentage of the total selling.
Max Discount (%): It is the maximum discount that you (as a service owner) can change here in percentage of the total selling. It is for banning your total discount from a specific number. When you set Z1 and Z2, it is probable that the discount becomes very high that is not acceptable by your side. Here you change the ban that your maximum discount be under your control.
Averaging Period (in second) It is the number that you have defined before (Item 5-9) and you can change here (please refer to the item 2-3).
Relaxation Period (in second) The commission of the promoters is calculated based on the averaging sale (please refer to the item 2-3) that is calculated based on the averaging period (item 5-10). The relaxation period can be changed here so the promoters’ effort will not be ruined if he/she does not sell for a period of time. In other word the averaging sale will not become low for a period of time.
Website Here you can change the website of the selected service.
Dex Router ??????????????????
Submit You can finish your work by pressing the “Submit” button. So, your change has been set.

 

• Service’s history and Cluster’s History:

Here is the service and cluster history which may be shown in Fig. 16.

 

Fig. 16: Service's History & Cluster's History.

 

- Service’s History:

In this graph you can see your own service performance of the selected service. The income, the sale count, the sale average and the promoter count may be shown in the current graph.

 

- Cluster’s History:

In this graph, the rank of your cluster, the sale count, the sale average and the number of the promoters may be seen simultaneously.

 

Hint: The graphs may be changed by varying the service

 

• Promoter's History:

The performance of the promoters of selected service is shown in the Fig. 17.

 

Fig. 17: Promoter's History.

 

In the Fig. 17, the selective cluster commission (%) that should be paid, the specific promoter commission or direct commission (%), the sale count and the sale average of the selective service is shown.

 

CryptuLotto® (Cryptu Lottery)


 

 

Cryptu Lottery (CryptuLotto®) is a secure and reliable lottery platform in which gives the players the chance to raise money by buying ticket(s). If the digits on your ticket(s) match the winning numbers in correct order, you win a portion of the prize pool. There are three stages to play:

 

Stage 1: Buy Ticket(s)

 

• You may buy one ticket or more than it. Each ticket costs 2.49 USDT in $FARTY.

 

Stage 2: Wait for the Draw

 

• Since there is one draw each 24 hours, so you should wait until the final winning number is declared by the platform.

 

Stage 3: Check your ticket(s)

 

• The digits of your ticket(s) should match the winning number in the correct order, so come back to the CryptuLotto® and check to see if you`ve won!

 

Cryptu Lottery Contract


 

 

CryptuLotto® Contract


Cryptu Lottery V1

 

Fork of PancakeSwap Lottery contract by using ChainLinkVRF2 V2 and Cryptu Promotion Ecosystem (CryptuProEco®).


Contract info

 

Contract name: CryptuLottery

 

Contract address: 0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c

 

Random number generator address: 0x8c6375Aab6e5B26a30bF241EBBf29AD6e6c503c2 (Random number generator contract must be deployed first)

 

View CryptuLottery.sol on BscScan.

 

View the Cryptu.io: Lottery contract on BscScan.


Lottery Status states

 

The lottery has four status states as Pending, Open, Close, and Claimable, which determine the actions that can or cannot be taken at a given time.

 

Read/View Function

 

viewCurrentLotteryId

 

 
function injectFunds(uint256 _lotteryId, uint256 _amount) external override onlyOwnerOrInjector {
						

 

Returns the ID of the current Lottery round as an integer. Round IDs correlate to round number, and are incremental, e.g. the ninth round of Lottery will be 9.

 

viewLottery

 

 
function viewLottery(uint32 _lotteryId) external view returns (Lottery memory);
						

 

Returns information on specified Lottery round as tuple (see Lottery structure below).

 

 
struct Lottery {
        Status status;
        uint256 startTime;
        uint256 endTime;
        uint256 priceTicketInCake;
        uint256 discountDivisor;
        uint256 amountCollectedInCake;
        uint256 treasuryFee; // 500: 5% // 200: 2% // 50: 0.5%
        uint256[6] cakePerBracket;
        uint64 firstTicketIdNextLottery;//gas opt 
        uint64 firstTicketId;//gas opt
        uint32 finalNumber;
        uint32 numberOfPlayers;//@dev: new feature added by Cryptu//gas opt
        uint16[6] rewardsBreakdown;//gas opt // 0: 1 matching number // 5: 6 matching numbers
        uint32[6] countWinningsPerBracket;//gas opt
    }
						

 

Name Type Description
status Status Pending, Open, Close, Claimable.
startTime uint256 Starting block for Lottery round.
endTime uint256 Ending block for Lottery round (approximately 12 hours after a round begins).
priceTicketInCake uint256 The price of a ticket in CAKE (approximately $2.49 USDT).
discountDivisor uint256 The divisor used to calculate bulk ticket discount.
amountCollectedInCake uint256 The amount of CAKE collected through ticket sales for the Lottery round.
treasuryFee uint256 Amount taken from funds raised per round that's moved to treasury address (maximum 3000).
cakePerBracket uint256[6] The amount of CAKE to distribute to winners of each bracket.
firstTicketIdNextLottery uint64 ID of the first ticket, set at the closing of current round that determines the range of eligible tickets for the current round.
firstTicketId uint64 ID of the first ticket, set with the opening of the Lottery round that determines the range of eligible tickets for the current round.
FinalNumber uint32 The winning ticket number of this round in reverse order.
numberOfPlayers uint32 Number of wallets, which purchased ticket in this round.
rewardsBreakdown uint16[6] The division of rewards across brackets (total must add up to 10,000).
countWinnersPerBracket uint32[6] Moves through brackets, starting from the highest, accounting for winners when value > 0.

 

viewNumbersAndStatusesForTicketIds

 

 
function viewNumbersAndStatusesForTicketIds(uint64[] calldata _ticketIds)
        external
        view
        returns (uint32[] memory, bool[] memory)
						

 

Returns the corresponding numbers and the statuses of ticketIds array of tickets defined by their ticketId.

 

 

viewRewardsForTicketId

 

 
function viewRewardsForTicketId(
        uint32 _lotteryId,
        uint32 _ticketId,
        uint32 _bracket
    ) external view returns (uint256)
						

 

Calculates rewards for a ticket after draw given the lotteryId, ticketId, and bracket. Filling and querying will provide a link to detailed price information on BscScan.

 

Name Type Description
lotteryId uint32 The ID of the Lottery.
ticketId uint32 The ID of the ticket.
bracket uint32 Bracket for the ticketId to verify the claim and calculate rewards.

 

viewUserInfoForLotteryId

 

 
function viewUserInfoForLotteryId(
        address _user,
        uint32 _lotteryId,
        uint32 _cursor,
        uint32 _size
    )
        external
        view
        returns (
            uint64[] memory,
            uint32[] memory,
            bool[] memory,
            uint256
    )
						

 

Returns user lotteryTicketIds, ticketNumbers, ticketStatuses and current data cursor of a user for a given Lottery (defined by lotteryId).

 

Name Type Description
User address The address of the user.
lotteryId uint32 The ID of the Lottery.
cursor uint32 Cursor to start where to retrieve the tickets.
size uint32 The number of tickets to retrieve.

 

viewRewardsForTicketId

 

 
function viewRewardsForTicketId(
        uint32 _lotteryId,
        uint32 _ticketId,
        uint32 _bracket
    ) external view returns (uint256)
						

 

Calculates rewards for a ticket after draw given the lotteryId, ticketId, and bracket.

 

Name Type Description
lotteryId uint32 The ID of the Lottery.
ticketId uint32 The ID of the ticket.
bracket uint32 Bracket for the ticketId to verify the claim and calculate rewards.

 

calculateTotalPriceForBulkTickets

 

 
function calculateTotalPriceForBulkTickets(
        uint256 _discountDivisor,
        uint256 _priceTicket,
        uint256 _numberTickets,
        bytes10 _refCode
    ) external view returns (uint256)
						

 

Calculates the price for a set of tickets accounting for bulk and referral code (Cryptu.io added this new feature) discount.

 

discountDivisor:

 

totalPriceForBulkTickets = priceSingleTicket * numberTickets * (discountDivisor +1 - numberTicket) / discountDivisor

 

Filling and querying will provide a link to detailed price information on BscScan.

 

Name Type Description
discountDivisor uint256 The divisor for the discount.
priceTickets uint256 The price of a ticket in CAKE.
numberTickets uint256 The number of tickets to buy.
refCode bytes10 10 bytes, zero padded referral code from Cryptu Promotion Manager Ecosystem. Must be 0 if no referral code is supplied.

 

viewUserWinningTickets (Cryptu.io added this new feature)

 

 
function viewUserWinningTickets(address _user,uint32 _lotteryId) external view returns(uint256 , WinningTicket[] memory )
						

Returns array of WinnigTicket structures for the user in the Lottery that its lotteryId is supplied in.

 

Name Type Description
user address The address of the user.
lotteryId uint32 The ID of the Lottery.

 

 
struct WinningTicket{//gas opt
        bool claimed;
        uint8 bracket;
        uint32 number;
        uint64 id;
        uint256 prize;
    }						
						

 

Name Type Description
claimed bool Whether the ticket is claimed or not.
bracket uint8 The bracket that this ticket is winning in it.
number uint32 Ticket number.
id uint64 The Lottery ID.
prize uint256 The amount of Cake token that this ticket is won..

 

ViewUserLotteries (Cryptu.io added this new feature)

 

 
function viewUserLotteries(address _user) external view returns(uint32 [] memory)					
						

 

Returns array of lottery ids that this user is participated in.

 

Write Functions (User)

 

buyTickets

 

 
function buyTickets(uint32 _lotteryId, uint32[] calldata _ticketNumbers,bytes10 _refCode/*Promotion Manager Support*/) external override notContract nonReentrant						
						

 

Buy tickets for the current Open Lottery round (between 1 and 100 per purchase). Calculates the price per ticket using calculateTotalPriceForBulkTickets.

 

Name Type Description
lotteryId uint32 The id of the lottery.
ticketNumbers uint32[] Array of ticket numbers between 1,000,000 and 1,999,999.
refCode bytes10 10 bytes, zero padded referral code from Cryptu Promotion Manager Ecosystem. Must be 0 if no referral code is supplied.

 

claimTickets

 

 
function claimTickets(uint32 _lotteryId,uint64[] calldata _ticketIds, uint32[] calldata _brackets) external override notContract nonReentrant						
						

 

Claim a set of winning tickets for a claimable lottery round. Checks lotteryId to determine if round is claimable, ownership of ticketId, eligibility of ticket (ticketId falls between firstTicketId and firstTicketIdNextLottery), and whether ticketId falls within eligible prize bracket (between 0 and 5).

 

Name Type Description
lotteryId uint32 The ID of the lottery.
ticketIds uint64[] Array of ticketIds.
brackets uint32[] Array of brackets for the ticket ids.

 

Write Functions (Operator/Admin)

 

closeLottery

 

 
function closeLottery(uint32 _lotteryId) external override onlyOperator nonReentrant
						

 

Closes the open lottery to close state. Emits LotteryClose event.

 

Name Type Description
lotteryId uint32 The ID of the lottery.

 

drawFinalNumberAndMakeLotteryClaimable

 

 
function drawFinalNumberAndMakeLotteryClaimable(uint32 _lotteryId, bool _autoInjection) external override onlyOperator nonReentrant
						

 

Lottery must be in close state. Draws the final Lottery number for results from randomResult, calculates the rewards for brackets after accounting for treasury fee, makes Lottery state Claimable, and transfers treasury fee to treasury address.

 

Name Type Description
lotteryId uint32 The ID of the lottery.
autoInjection boll Automatic injection status.

 

changeRandomGenerator

 

 
function changeRandomGenerator(address _randomGeneratorAddress) external OnlyOwner
						

 

Changes the random number generator contract address. Lottery must be Claimable.

 

Name Type Description
randomGeneratorAddress address The random generator address..

 

injectFunds

 

 
function injectFunds(uint32 _lotteryId, uint256 _amount) external override onlyOwnerOrInjector
						

 

Inject funds into a Lottery. Lottery must be Open.

 

Name Type Description
lotteryId uint32 The id of the lottery.
amount unit256 Amount, in CAKE token, to inject.

 

startLottery

 

 
function startLottery(
        uint256 _endTime,
        uint256 _priceTicketInCake,
        uint256 _discountDivisor,
        uint16[6] calldata _rewardsBreakdown,
        uint256 _treasuryFee
    ) external override onlyOperator
						

 

Starts the Lottery, setting it to Open state. Status must be Claimable.

 

Name Type Description
endTime uint256 End time of the Lottery.
priceTicketInCake unit256 Price of a ticket in CAKE.
discountDivisor uint256 The divisor to calculate the discount magnitude for bulks.
rewardsBreakdown uint16[6] Breakdown of rewards per bracket (must sum to 10,000).
trasuryFee uint256 Treasury fee (10,000 = 100%, 100 = 1%).

 

recoverWrongTokens

 

 
function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner
						

 

Allows admin to recover incorrect tokens sent to address mistakenly. Cannot be CAKE tokens.

 

Name Type Description
tokenAddress address The address of the token to withdraw.
tokenAmount unit256 The number of tokens to withdraw.

 

setMinAndMaxTicketPriceInCake

 

 
function setMinAndMaxTicketPriceInCake(uint256 _minPriceTicketInCake, uint256 _maxPriceTicketInCake) external onlyOwner
						

 

Allows admin to set upper and lower limit of ticket price in CAKE value. Minimum price must be lower than maximum price.

 

Name Type Description
minPriceTicketInCake uint256 The minimum price in CAKE.
maxPriceTicketInCake unit256 The maximum price in CAKE.

 

setMaxNumberTicketsPerBuy

 

 
function setMaxNumberTicketsPerBuy(uint256 _maxNumberTicketsPerBuy) external onlyOwner
						

 

Set max number of tickets purchasable at a time (presently 100). Max number of tickets must be higher than 0.

 

Name Type Description
maxNumberTicketsPerBuy uint256 Max number of tickets in one purchase.

 

setOperatorAndTreasuryAndInjectorAddress

 

 
function setOperatorAndTreasuryAndInjectorAddresses(
        address _operatorAddress,
        address _treasuryAddress,
        address _injectorAddress
    ) external onlyOwner
						

 

Sets the address of the Lottery operator.

 

Name Type Description
operatorAddress address The address of the operator.
treasuryAddress address The address of the treasury.
injectorAddress address The address of the injector.

 

Events (User)

 

TicketsPurchase

 

 
event TicketsPurchase(address indexed buyer, uint32 indexed lotteryId, uint32 numberTickets);
						

 

Lottery tickets are purchased.

 

Emitter: buyTickets go to buyTickets.

 

 

TicketsClaim

 

 
event TicketsClaim(address indexed claimer, uint256 amount, uint32 indexed lotteryId, uint32 numberTickets);
						

 

Lottery tickets are claimed post-draw.

 

Emitter: claimTickets go to claimTickets.

 

 

OnCommisionTransfered

 

 
event OnCommisionTransfered(uint256 amount,bytes10 refCode);//optional event that shows the commission transfer
						

 

Optional event for commission transfer to the Cryptu Promotion Manager contract, can be emitted in buyTicket function.

 

Events (Admin)

 

AdminTokenRecovery

 

 
event AdminTokenRecovery(address token, uint256 amount);
						

 

Admin recovers incorrect tokens from Lottery address.

 

Emitter: recoverWrongTokens go to recoverWrongTokens.

 

LotteryClose

 

 
event LotteryClose(uint32 indexed lotteryId, uint64 firstTicketIdNextLottery);
						

 

The Lottery is closed. lotteryId is indexed and firstTicketIdNextLottery is determined by currentTicketId.

 

Emitter: closeLottery go to closeLottery.

 

LotteryInjection

 

 
event LotteryInjection(uint32 indexed lotteryId, uint256 injectedAmount);
						

 

Funds are injected into Lottery.

 

Emitter: injectFunds go to injectFunds.

 

LotteryOpen

 

 
event LotteryOpen(uint32 indexed lotteryId,uint256 startTime,
        uint256 endTime,uint256 priceTicketInCake,
        uint64 firstTicketId,uint256 injectedAmount);
						

 

The Lottery is opened. firstTicketId is set from currentTicketId,

 

Emitter: startLottery go to startLottery.

 

LotteryNumberDrawn

 

 
event LotteryNumberDrawn(uint32 indexed lotteryId, uint32 finalNumber, uint32 countWinningTickets);
						

 

Lottery numbers are drawn for Lottery round.

 

Emitter: drawFinalNumberAndMakeLotteryClaimable go to drawFinalNumberAndMakeLotteryClaimable.

 

NewOperatorAndTreasuryAndInjectorAddresses

 

 
event NewOperatorAndTreasuryAndInjectorAddresses(address operator, address treasury, address injector);
						

 

New operator address is set.

 

Emitter: setOperatorAndTreasuryAndInjectorAddresses go to setOperatorAndTreasuryAndInjectorAddresses.

 

NewRandomGenerator

 

 
event NewRandomGenerator(address indexed randomGenerator);
						

 

New random number generator address is set.

 

Emitter: changeRandomGenerator go to changeRandomGenerator.

 

Contract Roles

 

Role Description
injectorAddress (onlyInjector) Injector is the address used to fund the lottery with periodic injections.
operatorAddress (onlyOperator) The lottery scheduler account used to run regular operations.
treasuryAddress (onlyTreasury) The address in which the burn is sent
Owner (onlyOwner) The contract owner

 

Role Description

 

Owner

 

0xad9d97fc7bf0ac6dc68d478dcb3709454519b358

 

Address controlled by gnosis multisignature contract with a threshold of 3/6

 

Operator Address

 

0x566a7e38b300E903dE71389C2b801AcDBA5268dB

 

Scheduler address - entirely automated and no human interaction. Not on multisig and doesn't have access to sensitive contract operations.

 

Treasury Address

 

0xe2086f890e7bd20e07fc0036a437dc4813e88b09

 

Address controlled by gnosis multisignature contract with a threshold of 3/6

 

Injector Address (Currently the same as Owner)

 

0xaD9d97fc7BF0ac6dC68d478dcB3709454519b358

 

Address controlled by gnosis multisignature contract with a threshold of 3/6

 

 

Functions

 

injectFunds - Injector and Owner

 

 
function injectFunds(uint32 _lotteryId, uint256 _amount) external override
       onlyOwnerOrInjector {
       require(_lotteries[_lotteryId].status == Status.Open, "Lottery not open");
       cakeToken.safeTransferFrom(address(msg.sender), address(this), _amount);
       _lotteries[_lotteryId].amountCollectedInCake += _amount;
       emit LotteryInjection(_lotteryId, _amount);
    }
						

The Injector or Owner can call this function to inject a specific lotteryId with a specified amount of CAKE.

 

startLottery - Operator

 

 
function startLottery(
        uint256 _endTime,
        uint256 _priceTicketInCake,
        uint256 _discountDivisor,
        uint16[6] calldata _rewardsBreakdown,
        uint256 _treasuryFee
        ) external override onlyOperator {
        require(
        (currentLotteryId == 0) || (_lotteries[currentLotteryId].status == Status.Claimable),
        "Not time to start lottery"
        );
        require(
        ((_endTime - block.timestamp) > MIN_LENGTH_LOTTERY) && ((_endTime - block.timestamp) < MAX_LENGTH_LOTTERY),
        "Lottery length outside of range" );
        require(
        (_priceTicketInCake >= minPriceTicketInCake) && (_priceTicketInCake <= maxPriceTicketInCake),
        "Outside of limits"
        );
        require(_discountDivisor >= MIN_DISCOUNT_DIVISOR, "Discount divisor too low");
        require(_treasuryFee <= MAX_TREASURY_FEE, "Treasury fee too high");
        require(
        (_rewardsBreakdown[0] +
        _rewardsBreakdown[1] +
        _rewardsBreakdown[2] +
        _rewardsBreakdown[3] +
        _rewardsBreakdown[4] +
        _rewardsBreakdown[5]) == 10000,
        "Rewards must equal 10000"
        );
        currentLotteryId= _lowgas_inc_32(currentLotteryId);//gas opt /
        _lotteries[currentLotteryId] = Lottery({
        status: Status.Open,
        startTime: block.timestamp,
        endTime: _endTime,
        priceTicketInCake: _priceTicketInCake,
        discountDivisor: _discountDivisor,
        rewardsBreakdown: _rewardsBreakdown,
        treasuryFee: _treasuryFee,
        cakePerBracket: [uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0)],
        countWinningsPerBracket: [uint32(0), uint32(0), uint32(0), uint32(0), uint32(0), uint32(0)],
        firstTicketId: currentTicketId,
        firstTicketIdNextLottery: currentTicketId,
        amountCollectedInCake: pendingInjectionNextLottery,
        finalNumber: 0,
        numberOfPlayers:0
        });
        emit LotteryOpen(
        currentLotteryId,
        block.timestamp,
        _endTime,
        _priceTicketInCake,
        currentTicketId,
        pendingInjectionNextLottery
        );
        pendingInjectionNextLottery = 0;
    }
						

The startLottery function is only callable by the Operator in order to start a new lottery round.

 

closeLottery - Operator

 

 
function closeLottery(uint32 _lotteryId) external override onlyOperator nonReentrant {
        require(_lotteries[_lotteryId].status == Status.Open, "Lottery not open");
        require(block.timestamp > _lotteries[_lotteryId].endTime, "Lottery not over");
        require(block.timestamp > _lotteries[_lotteryId].endTime,uint2str(block.timestamp) );
        _lotteries[_lotteryId].firstTicketIdNextLottery = currentTicketId;
        //*************************************************************
        //new call using ChainLink VRF2
        randomGenerator.getRandomNumber();
        //*************************************************************
        _lotteries[_lotteryId].status = Status.Close;
        emit LotteryClose(_lotteryId, currentTicketId);
    }
						

Callable by the Operator to close a round of the lottery.

 

drawFinalNumberAndMakeLotteryClaimable - Operator

 

 
function drawFinalNumberAndMakeLotteryClaimable(uint32 _lotteryId, bool _autoInjection)
        external
        override
        onlyOperator
        nonReentrant
    {
        // Calculate the finalNumber based on the randomResult generated by ChainLink's fallback
        uint32 finalNumber =  randomGenerator.viewRandomResult();
        //******************************************************************************************
        //@dev: preventing number duplication due to lack of Link balance of random generator    
        if(currentLotteryId!=0)
        {
            if(_lotteries[currentLotteryId-1].finalNumber==finalNumber)//previous round number
                revert("Wrong final number!");
        }
        //*******************************************************************************************
        // Initialize a number to count addresses in the previous bracket
        uint32 numberAddressesInPreviousBracket;
        _lotteryId=_lotteryId;
        _autoInjection=true;
        // Calculate the amount to share post-treasury fee
        uint256 amountToShareToWinnings = (
        ((_lotteries[_lotteryId].amountCollectedInCake) * (10000 - _lotteries[_lotteryId].treasuryFee))
        ) / 10000;
        // Initializes the amount to withdraw to treasury
        uint256 amountToWithdrawToTreasury;
        // Calculate prizes in CAKE for each bracket by starting from the highest one
        for (uint32 i; i < 6;) {
        uint32 j = 5 - i;
        uint32 transformedWinningNumber = _bracketCalculator[j] + (finalNumber % (uint32(10)**(j + 1)));
        _lotteries[_lotteryId].countWinningsPerBracket[j] =
        _numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber] -
        numberAddressesInPreviousBracket;
        // A. If number of users for this _bracket number is superior to 0
        if (
        (_numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber] - numberAddressesInPreviousBracket) !=
        0
        ) {
        // B. If rewards at this bracket are > 0, calculate, else, report the numberAddresses from previous bracket
        if (_lotteries[_lotteryId].rewardsBreakdown[j] != 0) {
        _lotteries[_lotteryId].cakePerBracket[j] =
        ((_lotteries[_lotteryId].rewardsBreakdown[j] * amountToShareToWinnings) /
        (_numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber] -
        numberAddressesInPreviousBracket)) /
        10000;
        // Update numberAddressesInPreviousBracket
        numberAddressesInPreviousBracket = _numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber];
        }
        // A. No CAKE to distribute, they are added to the amount to withdraw to treasury address
        } else {
        _lotteries[_lotteryId].cakePerBracket[j] = 0;
        amountToWithdrawToTreasury +=
        (_lotteries[_lotteryId].rewardsBreakdown[j] * amountToShareToWinnings) /
        10000;
        }
        unchecked{++i;}//gas opt
        }
        // Update internal statuses for lottery
        _lotteries[_lotteryId].finalNumber = finalNumber;
        _lotteries[_lotteryId].status = Status.Claimable;
        if (_autoInjection) {
        pendingInjectionNextLottery = amountToWithdrawToTreasury;
        amountToWithdrawToTreasury = 0;
        }
        amountToWithdrawToTreasury += (_lotteries[_lotteryId].amountCollectedInCake - amountToShareToWinnings);
        // Transfer CAKE to treasury address
        if(amountToWithdrawToTreasury!=0)//@dev
        cakeToken.safeTransfer(treasuryAddress, amountToWithdrawToTreasury);
        emit LotteryNumberDrawn(currentLotteryId, finalNumber, numberAddressesInPreviousBracket);
    }
						

For Operator to draw the final number using ChainLink VRF2 function.

 

recoverWrongTokens - Owner

 

 
function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount)
       external onlyOwner {
        require(_tokenAddress != address(cakeToken), "Cannot be CAKE token");
        IERC20(_tokenAddress).safeTransfer(address(msg.sender), _tokenAmount);
        emit AdminTokenRecovery(_tokenAddress, _tokenAmount);
    }
						

In the case of tokens other than CAKE mistakenly being sent to the lottery contract, this function is used to recover them and is only callable by the Owner.

 

setMinAndMaxTicketPriceInCake - Owner

 

 
function setMinAndMaxTicketPriceInCake(uint256 _minPriceTicketInCake, uint256 _maxPriceTicketInCake)
        external
        onlyOwner
    {
        require(_minPriceTicketInCake <= _maxPriceTicketInCake, "minPrice must be < maxPrice");
        minPriceTicketInCake = _minPriceTicketInCake;
        maxPriceTicketInCake = _maxPriceTicketInCake;
    }
						

To prevent the Operator setting the tickets to arbitrary prices during the event of a flash crash/pump.

 

setMaxNumberTicketsPerBuy - Owner

 

 
function setMaxNumberTicketsPerBuy(uint256 _maxNumberTicketsPerBuy) external onlyOwner {
        require(_maxNumberTicketsPerBuy != 0, "Must be > 0");
        maxNumberTicketsPerBuyOrClaim = _maxNumberTicketsPerBuy;
    }
						

The Owner can modify the maximum number of tickets per transaction. This may be modified in the case of BSC block size increasing or decreasing.

 

setOperatorAndTreasuryAndInjectorAddresses - Owner

 

 
function setOperatorAndTreasuryAndInjectorAddresses(
        address _operatorAddress,
        address _treasuryAddress,
        address _injectorAddress
        ) external onlyOwner {
        require(_operatorAddress != address(0), "Cannot be zero address");
        require(_treasuryAddress != address(0), "Cannot be zero address");
        require(_injectorAddress != address(0), "Cannot be zero address");
        operatorAddress = _operatorAddress;
        treasuryAddress = _treasuryAddress;
        injectorAddress = _injectorAddress;
        emit NewOperatorAndTreasuryAndInjectorAddresses(_operatorAddress, _treasuryAddress, _injectorAddress);
    }
						

Function used to set the Operator, Treasury, and Injector addresses.

 

changeRandomGenerator

 

 
function changeRandomGenerator(address _randomGeneratorAddress) external onlyOwner {
        require(_lotteries[currentLotteryId].status == Status.Claimable, "Lottery not in claimable");
        //********************************************************************
        //@dev: using ChainLink VRF V2
        IRandomNumberGenerator(_randomGeneratorAddress).getRandomNumber();
        //********************************************************************
        // Calculate the finalNumber based on the randomResult generated by ChainLink's fallback
        IRandomNumberGenerator(_randomGeneratorAddress).viewRandomResult();
        randomGenerator = IRandomNumberGenerator(_randomGeneratorAddress);
        emit NewRandomGenerator(_randomGeneratorAddress);
    }
						

For the Owner to update the RandomNumberGenerator contract in case we need to update the drawing logic, or release an update.

 

CryptuLotto® How To Play


 

 

CryptuMint® (Cryptu Mint Token)


 

 

Cryptu Mint Token (CryptuMint®) is a professional platform that you can mint and generate your own tokens and record the information on to the specific blockchain without approving any banks or financial institutions and without any coding. In other word your own tokens are generated in decentralized method and in a few simple steps without the need for coding. There are two plans available on CryptuMint® for minting over 7 well-known crypto networks as follows:

 

Free:

 

• This plan is free of charge but in this choice, the token name and symbol cannot be searched in any blockchain networks and the probability of choosing a duplicate token name in this plan is very high.

 

Premium:

 

• This plan costs 10 USD that you can pay in ETH, USDT, BNB, FARTY, WBNB, MATIC, AVAX, DODGE and FTM by connecting your wallet. The token name and symbol can be searched by our engine in the selected blockchain networks to find any occurrence of your token's name in order to choose a unique name.

 

The well-known crypto networks are as Arbitrum One, Avalanche, BSC, Doge Chain, Ethereum, Fantom Opera and Polygone.


CryptuMint® Free Plan


 

 

CryptuMint® Free Plan is a professional platform under Cryptu.io that you can mint and generate your own tokens without approving any banks or financial institutions and without any coding.

 

Advantages:

 

• Totaly free of charge for minting token, except transaction fee for blockchain network.

 

• Create your crypto currency token without approving any banks or financial institutions and your own tokens are generated in decentralized method.

 

• Create your crypto currency token without any coding and in a few simple steps.

 

• Minting your crypto currency token over 7 well-known crypto networks are as Arbitrum One, Avalanche, BSC, Doge Chain, Ethereum, Fantom Opera and Polygone.

 

• ERC20 token types are available now.

 

• Get the TBC®, a free, unique and without any other example certificate in the crypto world for token which you have minted by CryptuMint® to show others the real date of your token’s birth and for the porpuse of anti scamming.

 

Disadvantages:

 

• The token name and symbol cannot be searched in any blockchain networks.

 

• The probability of choosing a duplicate token name in this plan is very high.


CryptuMint® Premium Plan


 

 

CryptuMint® Premium Plan is a professional platform under Cryptu.io that you can mint and generate your own tokens without approving any banks or financial institutions and without any coding.

 

Advantages:

 

• Totaly free of charge for minting token, except transaction fee for blockchain network and the TUC® cost.

 

• Only 10 USD cost to check the uniqueness of the token name and issue the TUC® that you can pay in ETH, USDT, BNB, FARTY, WBNB, MATIC, AVAX, DODGE and FTM by connecting your wallet.

 

• Powerfull and advanced search engine developed by Cryptu.io to check the token name and symbol in the selected blockchain networks to find any occurance of your token's name in order to choose a unique name.

 

• Create your crypto currency token without approving any banks or financial institutions and your own tokens are generated in decentralized method.

 

• Create your crypto currency token without any coding and in a few simple steps.

 

• Minting your crypto currency token over 7 well-known crypto networks are as Arbitrum One, Avalanche, BSC, Doge Chain, Ethereum, Fantom Opera and Polygone.

 

• ERC20 token types are available now.

 

• Get the TBC®, a free, unique and without any other example certificate in the crypto world for token which you have minted by CryptuMint® to show others the real date of your token’s birth and for the porpuse of anti scamming.

 

• Get the TUC®, a unique and without any other example certificate in the crypto world for token which you have minted by CryptuMint® or minted by third parties to show that your token name is unique in the selected blockchain networks till the date certified on the purchased TUC® for the porpuse of anti scamming.


CryptuMint® How To Mint


 

 

CryptuQuery® (Cryptu Token Query)


 

 

Cryptu Token Query (CryptuQuery®) is a comprehensive platform of our website in which the validity of certificates, that has been generated by Cryptu.io, can be checked. The QR code of TBC®/TUC® or token contract address may be checked in CryptuQuery® then system will show you if the certificates are ok or not.

CryptuQuery® How To Do


 

 

TBC® (TOKEN BIRTH CERTIFICATE®)


 

 

TOKEN BIRTH CERTIFICATE® (TBC®) is a free of charge certificate and it is without any other example in the crypto world in which you can show others the real date of your token’s birth which you have minted in CryptuMint® and you will recieve it from our side. In other word if another token is minted by your token name (after your token birth), you will prove by TBC® that your token is the first. Also, all TBCs will be equipped by a QR code that all people can search the validation of certificate in our comprehensive platform called CryptuQuery®.


TUC® (TOKEN UNITY CERTIFICATE®)


 

 

TOKEN UNITY CERTIFICATE® (TUC®) is a premium and paid certificate and it is without any other example in the crypto world that you may purchase it to show that your token name is unique in the selected blockchain networks. Our professional platform has the ability to search in several networks depends on your selection by powerfull and advanced search engine developed by Cryptu.io team. The price for TUC® is calculated by the networks selection and you can pay it in ETH, USDT, BNB, FARTY, WBNB, MATIC, AVAX, DODGE and FTM by connecting your wallet before achieving the certificate. In other word, if you mint by CryptuMint®, so you will have free of charge TBC® and you may purchase TUC®. Else if you have minted by others, so you can purchase your own TUC®. Also all TUCs equipped by a QR code that all people can search the validation of certificate in our comprehensive platform called CryptuQuery®.


$FARTY (OLD FART TOKEN)


 

 

$FARTY is the first meme coin ever exists to engage with a social-political real world's problem.

 

Since the day in which Satoshi invented the first crypto currency, the Bitcoin, several thousands of crypto currencies have been created. In 2013 Billy Markus and Jackson Palmer made the first joke coin (meme coin) the Doge, making fun only, but today the coin has a market capacity over 48 billion US dollars! According to the great victory of Doge, many meme coins have been developed over the net, such as Shiba Inu that is another successful meme token project.

 

But no meme coin ever exists to engage with a social-political real world's problem, all of them are just jokes!

 

In December of 2021, Tatashi Toushe founded the first meme token project that focuses on the problem of sleepy presidents. She named the token "Old Fart" after the US President Joe Biden farting at the COP26 climate talks in November 2021 to recall and bold the sleepy presidents' problem as a joke. So for more information about the $FARTY, please visit the OldFart Subdomain.


Fart Paper


 

 


In December of 2021, Tatashi Toushe founded the first meme token project that focuses on the social-political real world's problem. She named the token "Old Fart" and also created a new type of white paper, the "Fart Paper"! Just like the dog type meme coins Woof Paper! So for more information about the project, please read the Fart Paper!